首页 文章

将Xamarin Forms中的DateTime格式化为设备格式字符串

提问于
浏览
12

如何在运行PCL Xamarin.Forms项目时将 DateTime 对象格式化为设备默认日期时间格式的字符串,我的部署目标包括iOS,Android和Windows .

根据threadbugDateTime.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);

查看this SO问题以更清楚地理解需求(它仅适用于android,我希望它适用于所有平台,因为这是一个Xamarin.Forms问题) .

由于Xamarin Forms中的 DatePickerTimePicker 以设备格式显示日期和时间,我希望有一种方法可以在PCL中获取它 .

PCL中还有一个 Device 类,其中包含平台,习语等信息 .

2 回答

  • 4

    由于我找不到任何PCL实现,我使用DI来实现该要求 .

    在PCL中的用法:

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

    PCL:

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

    Android:

    [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);
                    }
                }
            }
        }
    }
    

    Windows:

    [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);
    
  • 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 .

相关问题