简体   繁体   English

将 Xamarin 表单中的日期时间格式化为设备格式字符串

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

How can I format a DateTime object to a string in the device default datetime format when running a PCL Xamarin.Forms project and my deployement targets include iOS, Android and Windows.在运行 PCL Xamarin.Forms 项目并且我的部署目标包括 iOS、Android 和 Windows 时,如何将DateTime对象格式化为设备默认日期时间格式的字符串。

The DateTime.ToShortString() doesn't work as per MSDN requirement according to this thread and this bug .根据此线程和此错误DateTime.ToShortString()无法按照 MSDN 要求工作。

Is there any Forms based solution or do I need to get it from platform specific projects?是否有任何基于表单的解决方案,或者我是否需要从特定于平台的项目中获取它?

For Android, I can do the following from Native project using DI:对于 Android,我可以使用 DI 从 Native 项目中执行以下操作:

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

OR I can use this too (the C# version of the below code):或者我也可以使用它(以下代码的 C# 版本):

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

Look into this SO question to understand the requirement more clearly (its only for android, I want it for all platforms as this is a Xamarin.Forms question).查看这个SO 问题以更清楚地了解需求(它仅适用于 android,我希望它适用于所有平台,因为这是一个 Xamarin.Forms 问题)。

Since the DatePicker and TimePicker in Xamarin Forms show the date and time in device format I am hoping there would a way to get it in the PCL.由于 Xamarin Forms 中的DatePickerTimePicker以设备格式显示日期和时间,我希望有办法在 PCL 中获取它。

Also there is a Device class in PCL which has information like platforms, idiom, etc. PCL 中还有一个Device类,它包含平台、习惯用法等信息。

As I could not find any PCL implementation I used DI to implement the requirement.由于我找不到任何 PCL 实现,我使用 DI 来实现需求。

Usage in PCL :在 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 : 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();
        }
    }
}

Helper method :辅助方法:

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

With the current Xamarin Forms version, you may try:使用当前的 Xamarin Forms 版本,您可以尝试:

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

This gives the date in a format specific to the device's locale and works across platforms.这以特定于设备的区域设置的格式提供日期并跨平台工作。

Alternatively:或者:

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

For specific format the following can be tried:对于特定格式,可以尝试以下方法:

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

The first and the last one look pretty cool to me.第一个和最后一个对我来说看起来很酷。 But only the second and the third options work with PCL.但只有第二个和第三个选项适用于 PCL。

Very similar to Rohit Vipin Mathews answer but without using helper methods.与 Rohit Vipin Mathews 的回答非常相似,但没有使用辅助方法。

For Android安卓版

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

For iOS对于 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