如何在运行PCL Xamarin.Forms项目时将DateTime
对象格式化为设备默认日期时间格式的字符串,我的部署目标包括iOS,Android和Windows。
根据此thread和此bug,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);
查看this SO问题以更清楚地理解需求(它仅适用于android,我希望它适用于所有平台,因为这是一个Xamarin.Forms问题)。
由于Xamarin Forms中的DatePicker
和TimePicker
以设备格式显示日期和时间,我希望有一种方法可以在PCL中获取它。
PCL中还有一个Device
类,其中包含平台,习语等信息。
答案 0 :(得分: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 :(得分: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。
答案 2 :(得分:0)
与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));
}
}