为什么DAY_OF_WEEK增加了一天?

时间:2019-06-09 00:32:20

标签: java android android-calendar

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 Emulator上对此进行了测试。 cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY不断返回true

-编辑-

我也尝试过:

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

这将返回1

1 个答案:

答案 0 :(得分:1)

tl; dr

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.
  

萨米迪

问题

  • 您输入的内容显然是秒数,而不是milliseconds
  • 您使用的是可怕的旧日期时间类,而这些类早已被现代 java.time 类取代。
  • 您隐式地介绍了时区问题,没有立即解决它们。时区对于感知日期(以及星期几)至关重要。

java.time

您输入的数字1_560_049_200L显然是UTC 1970年第一时刻以来的整数秒。您的代码错误地将它们解析为毫秒计数。

解析为Instant

Instant instan = Instant.ofEpochSecond( 1_560_049_200L ) ;
  

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

调整到您想要感知日期的时区,因此要调整为一周中的一天。

Continent/Region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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

zdt.toString():2019-06-08T23:00-04:00 [美国/蒙特利尔]

请注意日期之间的差异: UTC的第9位与魁北克的第8位。请记住:在任何给定时刻,日期在全球范围内都会有所不同。东部是“明天”,而西部仍然是“昨天”。

不同的日期意味着不同的星期几。 星期六在魁北克,它同时也是星期日在巴黎。这就是为什么指定时区至关重要的原因。

提取星期几。

DayOfWeek dow = zdt.getDayOfWeek() ;
  

dow.toString():星期六

本地化星期几的名称。

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

萨米迪

或者,Locale.US代表美国。

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

星期六

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