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.
The DateTime.ToShortString()
doesn't work as per MSDN requirement according to this thread and this bug.
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:
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):
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).
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.
Also there is a Device
class in PCL which has information like platforms, idiom, etc.
With the current Xamarin Forms version, you may try:
// 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.
As I could not find any PCL implementation I used DI to implement the requirement.
Usage in 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();
}
}
}
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With