ces*_*nux 68 java android date
我有几个事件的日期,以毫秒 [1] 表示,我想知道哪些事件在当前周和当月,但我无法弄清楚如何获得第一天(日/月/年) )运行周并将其转换为毫秒,同一个月的第一天.
[1]Since January 1, 1970, 00:00:00 GMT
Run Code Online (Sandbox Code Playgroud)
COM*_*ROM 146
本周以毫秒为单位:
// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
// get start of this week in milliseconds
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
System.out.println("Start of this week: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
// start of the next week
cal.add(Calendar.WEEK_OF_YEAR, 1);
System.out.println("Start of the next week: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
Run Code Online (Sandbox Code Playgroud)
本月以毫秒为单位:
// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
// get start of the month
cal.set(Calendar.DAY_OF_MONTH, 1);
System.out.println("Start of the month: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
// get start of the next month
cal.add(Calendar.MONTH, 1);
System.out.println("Start of the next month: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
Run Code Online (Sandbox Code Playgroud)
Bal*_*usC 23
一周的第一天可以通过以下方式确定java.util.Calendar
:
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeInMillis(timestamp);
while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}
long firstDayOfWeekTimestamp = calendar.getTimeInMillis();
Run Code Online (Sandbox Code Playgroud)
每月的第一天可以确定如下:
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeInMillis(timestamp);
while (calendar.get(Calendar.DATE) > 1) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of month.
}
long firstDayOfMonthTimestamp = calendar.getTimeInMillis();
Run Code Online (Sandbox Code Playgroud)
非常详细,是的.
Java 7将带有一个改进的日期和时间API(JSR-310).如果你还没有切换,那么你可以使用JodaTime,这使得它不那么复杂:
DateTime dateTime = new DateTime(timestamp);
long firstDayOfWeekTimestamp = dateTime.withDayOfWeek(1).getMillis();
Run Code Online (Sandbox Code Playgroud)
和
DateTime dateTime = new DateTime(timestamp);
long firstDayOfMonthTimestamp = dateTime.withDayOfMonth(1).getMillis();
Run Code Online (Sandbox Code Playgroud)
Bas*_*que 13
Java 8及更高版本中的java.time框架取代了旧的java.util.Date/.Calendar类.旧的课程被证明是麻烦,混乱和有缺陷的.避免他们.
java.time框架的灵感来自于高度成功的Joda-Time库,由JSR 310定义,由ThreeTen-Extra项目扩展,并在教程中进行了解释.
Instant
本Instant
类代表在时间轴上一个时刻UTC.
java.time框架的分辨率为纳秒,或小数秒的9位数.毫秒只是小数秒的3位数.由于毫秒分辨率很常见,因此java.time包含一个方便的工厂方法.
long millisecondsSinceEpoch = 1446959825213L;
Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );
Run Code Online (Sandbox Code Playgroud)
millisecondsSinceEpoch:1446959825213即时:2015-11-08T05:17:05.213Z
ZonedDateTime
要考虑当前周和当月,我们需要应用特定时区.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
Run Code Online (Sandbox Code Playgroud)
在zoneId:America/Montreal,即:2015-11-08T00:17:05.213-05:00 [America/Montreal]
在日期时间工作中,我们通常使用半开放方法来定义时间跨度.开头是包容性的,而结尾是独家的.而不是试图确定一周(或月)结束的最后一个瞬间,我们得到的第一个瞬间以下星期(或月).所以一个星期从周一的第一时刻运行,并上升到但不包括在第一时刻以下星期一.
我们是一周的第一天,也是最后一天.java.time框架包括用于该with
方法和ChronoField
枚举的工具.
默认情况下,java.time使用ISO 8601标准.所以星期一是一周的第一天(1),星期日是最后一天(7).
ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );
Run Code Online (Sandbox Code Playgroud)
那个星期从:2015-11-02T00:17:05.213-05:00 [美国/蒙特利尔]到2015-11-09T00:17:05.213-05:00 [美国/蒙特利尔]
哎呀!查看这些值的时间.我们想要一天的第一时刻.一天的第一时刻并不总是00:00:00.000
因为夏令时(DST)或其他异常现象.所以我们应该让java.time代表我们进行调整.要做到这一点,我们必须通过LocalDate
课程.
ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.
firstOfWeek = firstOfWeek.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );
Run Code Online (Sandbox Code Playgroud)
那个星期从:2015-11-02T00:00-05:00 [美国/蒙特利尔]到2015-11-09T00:00-05:00 [美国/蒙特利尔]
同月也一样.
ZonedDateTime firstOfMonth = zdt.with ( ChronoField.DAY_OF_MONTH , 1 );
firstOfMonth = firstOfMonth.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextMonth = firstOfMonth.plusMonths ( 1 );
Run Code Online (Sandbox Code Playgroud)
该月的运行时间为:2015-11-01T00:00-04:00 [美国/蒙特利尔]至2015-12-01T00:00-05:00 [美国/蒙特利尔]
YearMonth
查看一对时刻是否在同一个月的另一种方法是检查相同的YearMonth
值.
例如,假设thisZdt
并且thatZdt
都是ZonedDateTime
对象:
boolean inSameMonth = YearMonth.from( thisZdt ).equals( YearMonth.from( thatZdt ) ) ;
Run Code Online (Sandbox Code Playgroud)
我强烈建议不要在几毫秒之内完成你的日期工作.这确实是日期时间类往往在内部工作的方式,但我们有一些原因.处理来自时代的计数是笨拙的,因为人们无法理解这些值,因此调试和记录很困难且容易出错.而且,正如我们已经看到的,可能会有不同的决议; 旧的Java类和Joda-Time库使用毫秒,而像Postgres这样的数据库使用微秒,现在java.time使用纳秒.
你会处理文本作为位,还是你让类,如String
,StringBuffer
和StringBuilder
处理这样的细节?
但是,如果你坚持,从一个ZonedDateTime
得到一个Instant
,并从那里得到一个毫秒计数从纪元.但请记住,此调用可能意味着数据丢失.您ZonedDateTime
/中可能包含的任何微秒或纳秒Instant
将被截断(丢失).
long millis = firstOfWeek.toInstant().toEpochMilli(); // Possible data loss.
Run Code Online (Sandbox Code Playgroud)
小智 13
您可以使用该java.time
包(从 Java8 起)来获取日/周/月的开始/结束。
下面的 util 类示例:
import org.junit.Test;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
public class DateUtil {
private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");
public static LocalDateTime startOfDay() {
return LocalDateTime.now(DEFAULT_ZONE_ID).with(LocalTime.MIN);
}
public static LocalDateTime endOfDay() {
return LocalDateTime.now(DEFAULT_ZONE_ID).with(LocalTime.MAX);
}
public static boolean belongsToCurrentDay(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfDay()) && localDateTime.isBefore(endOfDay());
}
//note that week starts with Monday
public static LocalDateTime startOfWeek() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MIN)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
}
//note that week ends with Sunday
public static LocalDateTime endOfWeek() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MAX)
.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
}
public static boolean belongsToCurrentWeek(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfWeek()) && localDateTime.isBefore(endOfWeek());
}
public static LocalDateTime startOfMonth() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MIN)
.with(TemporalAdjusters.firstDayOfMonth());
}
public static LocalDateTime endOfMonth() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MAX)
.with(TemporalAdjusters.lastDayOfMonth());
}
public static boolean belongsToCurrentMonth(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfMonth()) && localDateTime.isBefore(endOfMonth());
}
public static long toMills(final LocalDateTime localDateTime) {
return localDateTime.atZone(DEFAULT_ZONE_ID).toInstant().toEpochMilli();
}
public static Date toDate(final LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(DEFAULT_ZONE_ID).toInstant());
}
public static String toString(final LocalDateTime localDateTime) {
return localDateTime.format(DateTimeFormatter.ISO_DATE_TIME);
}
@Test
public void test() {
//day
final LocalDateTime now = LocalDateTime.now();
System.out.println("Now: " + toString(now) + ", in mills: " + toMills(now));
System.out.println("Start of day: " + toString(startOfDay()));
System.out.println("End of day: " + toString(endOfDay()));
System.out.println("Does '" + toString(now) + "' belong to the current day? > " + belongsToCurrentDay(now));
final LocalDateTime yesterday = now.minusDays(1);
System.out.println("Does '" + toString(yesterday) + "' belong to the current day? > " + belongsToCurrentDay(yesterday));
final LocalDateTime tomorrow = now.plusDays(1);
System.out.println("Does '" + toString(tomorrow) + "' belong to the current day? > " + belongsToCurrentDay(tomorrow));
//week
System.out.println("Start of week: " + toString(startOfWeek()));
System.out.println("End of week: " + toString(endOfWeek()));
System.out.println("Does '" + toString(now) + "' belong to the current week? > " + belongsToCurrentWeek(now));
final LocalDateTime previousWeek = now.minusWeeks(1);
System.out.println("Does '" + toString(previousWeek) + "' belong to the current week? > " + belongsToCurrentWeek(previousWeek));
final LocalDateTime nextWeek = now.plusWeeks(1);
System.out.println("Does '" + toString(nextWeek) + "' belong to the current week? > " + belongsToCurrentWeek(nextWeek));
//month
System.out.println("Start of month: " + toString(startOfMonth()));
System.out.println("End of month: " + toString(endOfMonth()));
System.out.println("Does '" + toString(now) + "' belong to the current month? > " + belongsToCurrentMonth(now));
final LocalDateTime previousMonth = now.minusMonths(1);
System.out.println("Does '" + toString(previousMonth) + "' belong to the current month? > " + belongsToCurrentMonth(previousMonth));
final LocalDateTime nextMonth = now.plusMonths(1);
System.out.println("Does '" + toString(nextMonth) + "' belong to the current month? > " + belongsToCurrentMonth(nextMonth));
}
}
Run Code Online (Sandbox Code Playgroud)
测试输出:
Now: 2020-02-16T22:12:49.957, in mills: 1581891169957
Start of day: 2020-02-16T00:00:00
End of day: 2020-02-16T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current day? > true
Does '2020-02-15T22:12:49.957' belong to the current day? > false
Does '2020-02-17T22:12:49.957' belong to the current day? > false
Start of week: 2020-02-10T00:00:00
End of week: 2020-02-16T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current week? > true
Does '2020-02-09T22:12:49.957' belong to the current week? > false
Does '2020-02-23T22:12:49.957' belong to the current week? > false
Start of month: 2020-02-01T00:00:00
End of month: 2020-02-29T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current month? > true
Does '2020-01-16T22:12:49.957' belong to the current month? > false
Does '2020-03-16T22:12:49.957' belong to the current month? > false
Run Code Online (Sandbox Code Playgroud)
alc*_*san 12
注意!
while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}
Run Code Online (Sandbox Code Playgroud)
是个好主意,但有一些问题:例如,我来自乌克兰,我国的calendar.getFirstDayOfWeek()是2(星期一).今天是1(星期日).在这种情况下,没有调用calendar.add.
所以,正确的方法是将">"更改为"!=":
while (calendar.get(Calendar.DAY_OF_WEEK) != calendar.getFirstDayOfWeek()) {...
Run Code Online (Sandbox Code Playgroud)