我目前正在开发需要处理日期,时间等信息的应用程序。我遇到了一个非常简单的问题:从给定日期(以毫秒为单位)获取一周中的正确日期。
我确定,知道当前日期的给定时间(以毫秒为单位)是正确的时间,问题在于_calendar
变量返回的日期是给定时间的一天之后。>
我尝试使用Java中的DateFormat或其他日期处理类,但是我当前用于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
接收到整数之后的第二天。结果是6。
private final String[] mDaysOfTheWeek
= {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
答案 0 :(得分:1)
它应该返回: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`.
请参阅此code run live at 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
的格式指定proper time zone name,例如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() ;
private final String [] mDaysOfTheWeek = {“星期一”,“星期二”,“星期三”,“星期四”,“星期五”,“星期六”,“星期日”};
无需自己动手。使用DayOfWeek
枚举。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 1 :(得分:0)
如果您观看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
中的索引(6-1-1)是星期六。
答案 2 :(得分:0)
正如预期的那样,它将返回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;