2015-09-25 4 views
3

Как создать дату/время в определенном часовом поясе и вывести a short ISO 8601 date/time with offset from UTC? Например, 15:00 по тихоокеанскому стандартному времени 08 сентября 2015 года должно выглядеть следующим образом:Вывод строки ISO 8601

2015-09-08T17:00:00-07:00 

Вот моя текущая попытка.

using System; 
using NodaTime; 
using NodaTime.Text; 

namespace ConsoleApplication1_Nodatime 
{ 
    class Program 
    { 
     public static void Log(string x) => Console.WriteLine(x); 
     public static void Read() => Console.ReadLine(); 

     static void Main(string[] args) 
     { 
      var localDateTime = new LocalDateTime(2015, 09, 08, 17, 0); 
      var zone = DateTimeZoneProviders.Tzdb.GetZoneOrNull("America/Vancouver"); 
      var zonedDateTime = localDateTime.InZoneStrictly(zone); 
      Log(zonedDateTime.ToOffsetDateTime().ToString()); 
      Read(); 
     } 
    } 
} 

Это работает, хотя кажется слишком много шагов.

  1. Создать LocalDateTime
  2. Создать DateTimeZone
  3. Преобразовать LocalDateTime к ZonedDateTime
  4. Преобразовать ZonedDateTime к OffsetDateTime

Как мы делаем это с меньшим количеством шагов?

+3

Имейте в виду, что API Нода Времени намеренно многословным, чтобы держать вас от предположений или полагаться на значения по умолчанию. Вы можете больше узнать о философии дизайна [здесь] (http://nodatime.org/1.3.x/userguide/design.html). –

+1

Вам не нужно преобразовывать его в 'OffsetDateTime'. Вы можете форматировать 'ZonedDatetime' напрямую, чтобы включить смещение. Но вы не должны ожидать смещения для «LocalDateTime» - в конце концов, у него нет * одного *. «17:00 по тихоокеанскому стандартному времени 08 сентября 2015 года» находится в определенном часовом поясе - хотя неясно, какой именно из них вы имеете в виду, так как большинство тихоокеанских часовых поясов будет находиться в тихом океане * Дневной свет * Время, а не Тихий * Стандарт * Время сентября восьмой. –

+1

Пожалуйста, старайтесь избегать изменения требований в вопросе. Сначала вы хотели, чтобы смещение представлялось как «-07: 00», затем «-07». Очевидно, что у этих форматов есть разные ответы ... пожалуйста, выберите, что вы хотите, и придерживайтесь его, чтобы избежать ответов, которые не соответствуют вопросу. –

ответ

4

Как указано в комментариях к вопросу, вам нужно только ZonedDateTime, чтобы добиться желаемого форматирования (нет необходимости в OffsetDateTime). Строка формата передает «общий» шаблон смещения так, чтобы минуты включались («средний формат»), только если смещение имеет минуты.

zonedDateTime.ToString(
    "yyyy-MM-ddTHH:mm:sso<g>", 
    System.Globalization.CultureInfo.InvariantCulture) 

Для краткости, здесь доступные модели офсетные документированные:

  • е: полный формат, отображающий всю информацию, в том числе долей секунды. Типичный текст рисунка: + HH: mm: ss.fff
  • l: длинный формат, отображающий информацию до второй. Типичный текст рисунка: + HH: mm: ss
  • m: Средний формат, отображающий информацию до минуты. Типичный текст шаблона: + ЧЧ: мм
  • s: Короткий формат, отображающий информацию вплоть до часа. Типичный текст рисунка: + HH
  • g: Общий узор. Форматирование зависит от значения, которое прошло:
    • Если смещение имеет дробные секунды, используется полный формат; в противном случае
    • Если смещение имеет секунды, используется длинный формат; в противном случае
    • Если смещение имеет минуты, используется формат носителя; в противном случае
    • Используется короткий формат. При разборе применяются другие шаблоны стандартного формата по одному за раз. Это шаблон формата по умолчанию.
  • G: В качестве g, но с использованием Z для смещения 0, как если бы он был Z-префиксом.

Источник: http://nodatime.org/1.3.x/userguide/offset-patterns.html

ORIGINAL ВОПРОС

С первоначальным запросом форматирования, как ISO-8601 всегда показывая замыкающий минут, вы можете использовать собственный формат строку ниже. По умолчанию он соответствует стандартам ISO-8601, который не требует конечного «: 00». Тем не менее, вы можете передать шаблон смещения, чтобы заставить форматирование вы хотели:

zonedDateTime.ToString(
    "yyyy-MM-ddTHH:mm:sso<m>", 
    System.Globalization.CultureInfo.InvariantCulture) 

Источник: http://nodatime.org/1.3.x/userguide/offset-patterns.html

ОБНОВЛЕНИЕ ДЛЯ УКОРАЧИВАЕТ КОД

Если вы просто хотите, чтобы сократить код, вы всегда можете обернуть код в вспомогательный метод - возможно, даже в качестве статического метода расширения.

public static class NodaTimeHelpers 
{ 
    public static Lazy<DateTimeZone> Zone = new Lazy<DateTimeZone>(
     () => DateTimeZoneProviders.Tzdb.GetZoneOrNull("America/Vancouver")); 
    public static string ToStringWithOffset(this LocalDateTime localDateTime) 
    { 
     if (localDateTime == null) 
      return ""; 
     var zonedDateTime = localDateTime.InZoneStrictly(Zone.Value); 
     return zonedDateTime.ToString(
      "yyyy-MM-ddTHH:mm:sso<g>", 
      System.Globalization.CultureInfo.InvariantCulture); 
    } 
} 

Это позволяет ваш локальный объект даты и времени, чтобы преобразовать в строку очень легко:

localDateTime.ToStringWithOffset(); 
+0

Что вы подразумеваете под «вы можете передать шаблон смещения ...» Как мы это делаем? –

+1

Часть «o » - это шаблон смещения. По умолчанию ToString() использует o (общий шаблон), который выполняет «-07» вместо «-07: 00», который вы ищете, когда в смещении нет минут. Ссылка ниже примерного кода показывает другие стандартные шаблоны смещения, которые вы можете выбрать. Ваше требование выполняется путем изменения с «o » на «o » для среднего формата, чтобы всегда показывать минуты в смещении. –

+1

Добавлено обновление, которое поможет сократить код с нужной форматированием. –

 Смежные вопросы

  • Нет связанных вопросов^_^