簡體   English   中英

將 Xamarin 表單中的日期時間格式化為設備格式字符串

[英]Format DateTime in Xamarin Forms to Device Format string

在運行 PCL Xamarin.Forms 項目並且我的部署目標包括 iOS、Android 和 Windows 時,如何將DateTime對象格式化為設備默認日期時間格式的字符串。

根據此線程和此錯誤DateTime.ToShortString()無法按照 MSDN 要求工作。

是否有任何基於表單的解決方案,或者我是否需要從特定於平台的項目中獲取它?

對於 Android,我可以使用 DI 從 Native 項目中執行以下操作:

String format = Settings.System.GetString(this.context.ContentResolver 
                                         , Settings.System.DateFormat);
string shortDateString = dateTime.ToString(format);

或者我也可以使用它(以下代碼的 C# 版本):

DateFormat dateFormat = android.text.format.DateFormat.getDateFormat(context);

查看這個SO 問題以更清楚地了解需求(它僅適用於 android,我希望它適用於所有平台,因為這是一個 Xamarin.Forms 問題)。

由於 Xamarin Forms 中的DatePickerTimePicker以設備格式顯示日期和時間,我希望有辦法在 PCL 中獲取它。

PCL 中還有一個Device類,它包含平台、習慣用法等信息。

由於我找不到任何 PCL 實現,我使用 DI 來實現需求。

在 PCL 中的用法:

DependencyService.Get<IDeviceInfoService>()?.ConvertToDeviceTimeFormat(DateTime.Now);    
DependencyService.Get<IDeviceInfoService>()?.ConvertToDeviceTimeFormat(DateTime.Now);

個人電腦:

public interface IDeviceInfoService
{
    string ConvertToDeviceShortDateFormat(DateTime inputDateTime);    
    string ConvertToDeviceTimeFormat(DateTime inputDateTime);
}

安卓 :

[assembly: Dependency(typeof(DeviceInfoServiceImplementation))]
namespace Droid.Services
{
    public class DeviceInfoServiceImplementation : IDeviceInfoService
    {
        public string ConvertToDeviceShortDateFormat(DateTime inputDateTime)
        {
            var dateFormat = Android.Text.Format.DateFormat.GetDateFormat(Android.App.Application.Context);
            var epochDateTime = Helper.ConvertDateTimeToUnixTime(inputDateTime, true);

            if (epochDateTime == null)
            {
                return string.Empty;
            }

            using (var javaDate = new Java.Util.Date((long)epochDateTime))
            {
                return dateFormat.Format(javaDate);
            }
        }

        public string ConvertToDeviceTimeFormat(DateTime inputDateTime)
        {
            var timeFormat = Android.Text.Format.DateFormat.GetTimeFormat(Android.App.Application.Context);
            var epochDateTime = Helper.ConvertDateTimeToUnixTime(inputDateTime, true);

            if (epochDateTime == null)
            {
                return string.Empty;
            }

            using (var javaDate = new Java.Util.Date((long)epochDateTime))
            {
                return timeFormat.Format(javaDate);
            }
        }
    }
}

IOS:

[assembly: Dependency(typeof(DeviceInfoServiceImplementation))]
namespace iOS.Services
{
    public class DeviceInfoServiceImplementation : IDeviceInfoService
    {
        public string ConvertToDeviceShortDateFormat(DateTime inputDateTime)
        {
            var timeInEpoch = Helper.ConvertDateTimeToUnixTime(inputDateTime);

            if (timeInEpoch == null)
            {
                return string.Empty;
            }

            using (var dateInNsDate = NSDate.FromTimeIntervalSince1970((double)timeInEpoch))
            {
                using (var formatter = new NSDateFormatter
                {
                    TimeStyle = NSDateFormatterStyle.None,
                    DateStyle = NSDateFormatterStyle.Short,
                    Locale = NSLocale.CurrentLocale
                })
                {
                    return formatter.ToString(dateInNsDate);
                }
            }
        }

        public string ConvertToDeviceTimeFormat(DateTime inputDateTime)
        {
            var timeInEpoch = Helper.ConvertDateTimeToUnixTime(inputDateTime);

            if (timeInEpoch == null)
            {
                return string.Empty;
            }

            using (var dateInNsDate = NSDate.FromTimeIntervalSince1970((double)timeInEpoch))
            {
                using (var formatter = new NSDateFormatter
                {
                    TimeStyle = NSDateFormatterStyle.Short,
                    DateStyle = NSDateFormatterStyle.None,
                    Locale = NSLocale.CurrentLocale
                })
                {
                    return formatter.ToString(dateInNsDate);
                }
            }
        }
    }
}

窗戶:

[assembly: Dependency(typeof(DeviceInfoServiceImplementation))]
namespace WinPhone.Services
{
    public class DeviceInfoServiceImplementation : IDeviceInfoService
    {
        public string ConvertToDeviceShortDateFormat(DateTime inputDateTime)
        {
            return inputDateTime.ToShortDateString();
        }

        public string ConvertToDeviceTimeFormat(DateTime inputDateTime)
        {
            return inputDateTime.ToShortTimeString();
        }
    }
}

輔助方法:

private static readonly DateTime EpochDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long? ConvertDateTimeToUnixTime(DateTime? date, bool isDatarequiredInMilliSeconds = false, DateTimeKind dateTimeKind = DateTimeKind.Local) => date.HasValue == false
            ? (long?)null
            : Convert.ToInt64((DateTime.SpecifyKind(date.Value, dateTimeKind).ToUniversalTime() - EpochDateTime).TotalSeconds) * (isDatarequiredInMilliSeconds ? 1000 : 1);

使用當前的 Xamarin Forms 版本,您可以嘗試:

// This does not work with PCL
var date1 = DateTime.Now.ToShortDateString();

這以特定於設備的區域設置的格式提供日期並跨平台工作。

或者:

var date1 = DateTime.Now.ToString(CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern);

對於特定格式,可以嘗試以下方法:

var date1 = DateTime.Now.ToString("dd-MM-yyyy");

第一個和最后一個對我來說看起來很酷。 但只有第二個和第三個選項適用於 PCL。

與 Rohit Vipin Mathews 的回答非常相似,但沒有使用輔助方法。

安卓版

public class DeviceServiceImplementation : IDeviceInfoService
{
    public string FormatTime(DateTime dateTime)
    {
        return DateUtils.FormatDateTime(Application.Context, (long) dateTime.ToUniversalTime()
            .Subtract(DateTime.UnixEpoch).TotalMilliseconds, FormatStyleFlags.ShowTime);
    }
}

對於 iOS

public class DeviceServiceImplementation : IDeviceInfoService
{
    public string FormatTime(DateTime dateTime)
    {
        using var nsDateFormatter = new NSDateFormatter
        {
            DateStyle = NSDateFormatterStyle.None,
            TimeStyle = NSDateFormatterStyle.Short,
            FormattingContext = NSFormattingContext.Standalone,
            Locale = NSLocale.CurrentLocale
        };
        return nsDateFormatter.StringFor(dateTime.ToNSDate()
            .AddSeconds(-1 * NSTimeZone.SystemTimeZone.GetSecondsFromGMT));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM