Почему DAY_OF_WEEK добавляет дополнительный день? - PullRequest
1 голос
/ 09 июня 2019
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1560049200);

cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY // this returns true

cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.US) // Outputs Monday instead of Sunday.

Почему DAY_OF_WEEK добавляет дополнительный день? Он должен вернуться в воскресенье, но он возвращается в понедельник.

Я проверил это в I / System.out, на моем устройстве Android и на эмуляторе Android. cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY продолжает возвращаться true.

-EDIT-

Я тоже пробовал:

Date date = new Date(1560049200);
date.getDay();

это возвращается 1.

1 Ответ

1 голос
/ 09 июня 2019

ТЛ; др

Instant                          // Represent a moment in UTC.
.ofEpochSecond(                  // Parse a count of whole seconds since 1970-01-01T00:00Z.
    1_560_049_200L               // Contemporary moments are about a billion and a half seconds since 1970-01-01T00:00Z.
)                                // Returns a `Instant` object.
.atZone(                         // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
    Zone.of( "Africa/Tunis" )    // Specify the time zone in which you are interested.
)                                // Returns a `ZonedDateTime` object.
.getDayOfWeek()                  // Returns one of the seven pre-defined enum objects, one for each day of the week, Monday-Sunday. Returns a `DayOfWeek` object.
.getDisplayName(                 // Localize the presentation of the name of the day of the week.
    TextStyle.FULL ,             // Specify how long or abbreviated should the name of the day of week be.
    new Locale ( "fr" , "TN" )   // Specify the human language and cultural norms to use in translating the name of the day of week.
)                                // Returns a `String` object.

Samedi

Проблемы

  • Ваш ввод, очевидно, представляет собой количество полных секунд , а не миллисекунд .
  • Вы используете ужасные старые классы даты и времени, которые были вытеснены несколько лет назад классами modern java.time .
  • Вы неявно представляете проблемы с часовым поясом , не решая их сразу Часовой пояс имеет решающее значение в восприятии даты (и дня недели).

java.time

Ваш введенный номер 1_560_049_200L, по-видимому, является счетчиком целых секунд с первого момента 1970 года в UTC. Ваш код по ошибке анализировал их как количество миллисекунд.

Разобрать как Instant.

Instant instan = Instant.ofEpochSecond( 1_560_049_200L ) ;

instant.toString (): 2019-06-09T03: 00: 00Z

Настройте часовой пояс, через который вы хотите воспринимать дату, и, следовательно, день недели.

Укажите собственное имя часового пояса в формате Continent/Region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 2-4 буквенные сокращения, такие как EST или IST, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

zdt.toString (): 2019-06-08T23: 00-04: 00 [Америка / Монреаль]

Обратите внимание на разницу в дате: 9-е в UTC против 8-го в Квебеке . Имейте в виду: в любой данный момент дата меняется по всему земному шару в зависимости от зоны. На востоке «завтра», а на западе «вчера».

Другая дата означает другой день недели. В то время как суббота в Квебеке, это одновременно воскресенье в Париже , Франция. Вот почему указание часового пояса имеет решающее значение.

Извлечение дня недели.

DayOfWeek dow = zdt.getDayOfWeek() ;

dow.toString (): СУББОТА

Локализуйте название дня недели.

String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH );

Samedi

Или Locale.US для США.

String output = dow.getDisplayName( TextStyle.FULL , Locale.US );

Суббота

Table of date-time types in Java, both modern and legacy

...