C# 将Xamarin表单中的DateTime格式化为设备格式字符串

C# 将Xamarin表单中的DateTime格式化为设备格式字符串,c#,datetime,xamarin,xamarin.forms,datetime-format,C#,Datetime,Xamarin,Xamarin.forms,Datetime Format,运行PCL Xamarin时,如何将DateTime对象格式化为设备默认日期时间格式的字符串。Forms项目和我的部署目标包括iOS、Android和Windows 根据此和此,DateTime.ToShortString()不符合MSDN要求 是否有任何基于表单的解决方案,或者我是否需要从特定于平台的项目中获得它 对于Android,我可以使用DI从本机项目执行以下操作: String format = Settings.System.GetString(this.context.Conten

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

根据此和此,
DateTime.ToShortString()
不符合MSDN要求

是否有任何基于表单的解决方案,或者我是否需要从特定于平台的项目中获得它

对于Android,我可以使用DI从本机项目执行以下操作:

String format = Settings.System.GetString(this.context.ContentResolver 
                                         , Settings.System.DateFormat);
string shortDateString = dateTime.ToString(format);
或者我也可以使用它(下面代码的C版本):

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

由于Xamarin表单中的
日期选择器
时间选择器
以设备格式显示日期和时间,我希望有一种方法可以在PCL中获得它


PCL中还有一个
设备
类,它包含平台、惯用语等信息。

因为我找不到任何PCL实现,所以我使用DI来实现需求

PCL中的用法:

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

[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表单版本,您可以尝试:

// 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的答案,但不使用辅助方法

对于Android

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

如果格式化是特定于客户端的,那么您可能需要考虑使用依赖项服务@AndresCastro-谢谢,但我正在寻找PCL的一个选项,是的,我知道可以通过DI为每个平台获取它。明白了,我认为只要使用dateTime.ToString(“d”)就可以了,因为它应该在当前的文化中应用ToString。老实说,我以前没试过。如果您想了解更改设备区域性时会发生什么情况,可能会很感兴趣。@AndresCastro-不,请参阅我添加的链接。@Rohit您能为所需的预期输出编写一个示例吗?
public class DeviceServiceImplementation : IDeviceInfoService
{
    public string FormatTime(DateTime dateTime)
    {
        return DateUtils.FormatDateTime(Application.Context, (long) dateTime.ToUniversalTime()
            .Subtract(DateTime.UnixEpoch).TotalMilliseconds, FormatStyleFlags.ShowTime);
    }
}
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));
    }
}