2016-06-15 3 views
8

Wie kann ich ein DateTime Objekt in einem String im standardmäßigen Datetime-Format des Geräts formatieren, wenn ein PCL Xamarin.Forms-Projekt ausgeführt wird und meine Implementierungsziele iOS, Android und Windows umfassen.Formatieren von DateTime in Xamarin Forms in Device Format Zeichenfolge

Die DateTime.ToShortString() funktioniert nicht entsprechend der MSDN-Anforderung gemäß dieser thread und dieser bug.

Gibt es irgendeine formularbasierte Lösung oder muss ich sie von plattformspezifischen Projekten bekommen?

Für Android, kann ich folgende von Native Projekt mit DI tun:

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

OR Ich kann diese verwenden (die C# Version des Code unten):

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

Blick in this SO Frage, um die Anforderung klarer zu verstehen (es ist nur für Android, ich will es für alle Plattformen, da dies eine Xamarin.Forms Frage ist).

Da die DatePicker und TimePicker in Xamarin Forms das Datum und die Uhrzeit im Geräteformat zeigen, hoffe ich, dass es eine Möglichkeit geben würde, es in der PCL zu bekommen.

Auch gibt es eine Device Klasse in PCL, die Informationen wie Plattformen hat, Idiom usw.

+0

Wahrscheinlich möchten Sie den Abhängigkeitsdienst verwenden, wenn die Formatierung mandantenspezifisch ist. https://developer.xamarin.com/guides/xamarin-forms/dependency-service/introduction/ –

+0

@AndresCastro - Danke, aber ich bin auf der Suche nach einer Option von PCL, ja, ich weiß, es könnte getan werden via DI bekommen es für jeden Plattform. –

+2

Gotcha, ich würde denken, dass nur mit dateTime.ToString ("d") arbeiten würde, wie es die ToString in der aktuellen Kultur anwenden sollte. Ich habe es ehrlich gesagt noch nicht getestet. Es könnte interessant sein zu sehen, was passiert, wenn Sie Ihre Gerätekultur ändern. –

Antwort

2

Da ich keine PCL Implementierung I DI verwendet finden konnte, um die Anforderung zu implementieren.

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

Fenster:

[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-Methode:

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

Mit der aktuellen Xamarin Version Forms, können Sie versuchen:

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

Dies gibt das Datum in einem Format, die spezifisch für das Gebietsschema des Geräts und funktioniert plattformübergreifend.

Alternativ:

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

Für spezielle Format können die folgenden versucht werden:

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

Die erste und die letzte schauen mir ziemlich cool. Aber nur die zweite und die dritte Option funktionieren mit PCL.