[英]Java Calendar doesn't get correct day of the week
我目前正在开发需要与日期,时间等配合使用的应用程序。 我遇到了一个非常简单的问题:从给定日期(以毫秒为单位)获取一周中的正确日期。 我肯定知道当前日期的给定时间(以毫秒为单位)是正确的,问题在于_calendar
变量返回的日期是给定时间的一天之后。
我尝试使用DateFormat或Java的其他日期处理类,但是当前用于android应用的最小API是22。
private void getDayOfTheWeek(Long dateInMillis) {
Date _date = new Date();
_date.setTime(dateInMillis);
Calendar _calendar = Calendar.getInstance();
_calendar.setTime(_date);
mDayOfTheWeek = mDaysOfTheWeek[_calendar.get(Calendar.DAY_OF_WEEK) - 1];
Log.d("FirebaseDay", mDayOfTheWeek + "; " + _calendar.getTimeInMillis());
}
例如对于日期: 1564088400000它应返回:5,即星期五,尽管_calendar.getTimeInMillis()
的记录值与给定的值相同
编辑:问题不在于它返回一个数字,我有一个字符串数组mDaysOfTheWeek
,它使我从_calendar
接收到整数后的_calendar
。 结果为6。
private final String[] mDaysOfTheWeek
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
它应该返回:5,即星期五,…6是返回的结果。
糟糕的Calendar
类有很多问题。
使用java.time代替。 计数是合理的(周一至周日为1-7),并且可以使时区行为可预测和明确。
重要提示:时区至关重要。 对于更东部的地区,您的时刻显示为星期五。 对于其他西部地区,您的时刻显示为星期四。
Instant // Represent a moment in UTC.
.ofEpochMilli( // Parse your count-from-epoch 1970-01-01T00:00:00Z.
1_564_088_400_000L // Use underscores where you like, to make numeric literals more readable.
) // Returns an `Instant` object.
.atZone( // Adjust from UTC to some time zone.
ZoneId.of( "Asia/Tokyo" ) // Specify time zone using `Continent/Region` format, never 2-4 letter pseudo-zones such as `EST` or `CST` or `IST`.
) // Returns a `ZonedDateTime` object.
.getDayOfWeek() // Returns a `DayOfWeek` object.
.getDisplayName( // Generate automatically-localized string for the name of the day-of-week.
TextStyle.FULL , // How long or abbreviated.
Locale.US // Locale determines (a) human language for translation, and (b) cultural norms for issues such as abbreviation, punctuation, capitalization.
) // Returns a `String`.
看到此代码在IdeOne.com上实时运行 。
星期五
如果您坚持周一至周日为1-7,请致电getValue
而不是.getDisplayName
。
.getValue()
5
我目前正在开发需要与日期,时间等配合使用的应用程序。
然后,您应该停止使用几年前通过JSR 310淘汰的可怕的日期时间类。仅使用现代的java.time类。 切勿使用Date
或Calendar
。
从给定日期(以毫秒为单位)开始。
如果您指的是自UTC 1970年第一时刻的纪元参考以来的毫秒数,请解析为Instant
。 Instant
表示UTC中的时刻,即时间轴上的特定点。
Instant instant = Instant.ofEpochMilli( 1_564_088_400_000L ) ;
看到此代码在IdeOne.com上实时运行。
Instant.toString():2019-07-25T21:00:00Z
得到正确的一周中的一天
从瞬间确定日期需要时区的上下文。 在任何给定的时刻,日期都会在全球范围内变化。 日期可以同时在法国巴黎的“明天”,而在蒙特利尔魁北克的“昨天”。
以Continent/Region
的格式指定正确的时区名称 ,例如America/Montreal
, Africa/Casablanca
或Pacific/Auckland
。 切勿使用2-4字母的缩写,例如EST
或IST
因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
要将时刻调整为时区, ZoneId
应用于Instant
以获得ZonedDateTime
。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
如果要通过UTC而不是其他时区查看日期,请使用OffsetDateTime
类。
ZoneOffset offset = ZoneOffset.UTC ; // Constant for UTC (an offset of zero hours-minutes-seconds).
OffsetDateTime odt = instant.atOffset( offset ) ;
如果您想走这条路线(UTC),请将下面代码中的zdt
替换为此odt
。
使用DayOfWeek
枚举查询一周中的某天。
DayOfWeek dow = zdt.getDayOfWeek() ;
例如:日期:1564088400000,应返回:5
不,我建议您使用智能对象,而不要使用哑整数。 而不是使用5
表示Friday
(顺便说一句,在美国将表示Thursday
),而是在代码库中传递DayOfWeek
枚举对象。
要报告要使用的星期几,请进行本地化。
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ;
或者,如果您坚持要使用星期一到星期日的1-7的ISO 8601编号方案生成一个数字。
int dayOfWeekNumber = dow.getValue() ;
私有最终String [] mDaysOfTheWeek = {“星期一”,“星期二”,“星期三”,“星期四”,“星期五”,“星期六”,“星期日”};
无需自己动手。 使用DayOfWeek
枚举。
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的旧式日期时间类,例如java.util.Date
, Calendar
和SimpleDateFormat
。
要了解更多信息,请参见Oracle教程 。 并在Stack Overflow中搜索许多示例和说明。 规格为JSR 310 。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
您可以直接与数据库交换java.time对象。 使用与JDBC 4.2或更高版本兼容的JDBC驱动程序 。 不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目为将来可能在java.time中添加内容提供了一个试验场。 您可以在这里找到一些有用的类,比如Interval
, YearWeek
, YearQuarter
,和更多 。
如果看Calendar
课
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Sunday.
*/
public final static int SUNDAY = 1;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Monday.
*/
public final static int MONDAY = 2;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Tuesday.
*/
public final static int TUESDAY = 3;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Wednesday.
*/
public final static int WEDNESDAY = 4;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Thursday.
*/
public final static int THURSDAY = 5;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Friday.
*/
public final static int FRIDAY = 6;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Saturday.
*/
public final static int SATURDAY = 7;
因此, 1564088400000的星期几返回6( public final static int FRIDAY = 6;
)。 5.您的mDaysOfTheWeek
是Saturday 。
正如预期的那样,它将返回6,即星期五。 但是您的字符串数组mDaysOfTheWeek设置错误。
参考:
从类Calendar.java
public final static int SUNDAY = 1;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Monday.
*/
public final static int MONDAY = 2;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Tuesday.
*/
public final static int TUESDAY = 3;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Wednesday.
*/
public final static int WEDNESDAY = 4;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Thursday.
*/
public final static int THURSDAY = 5;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Friday.
*/
public final static int FRIDAY = 6;
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Saturday.
*/
public final static int SATURDAY = 7;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.