tl;dr
YearMonth
.of( 2023 , Month.NOVEMBER )
.atDay( 1 )
.atStartOfDay( ZoneId.of( "Asia/Kolkata" ) )
.toInstant()
.toEpochMilli()
…以及:
YearMonth
.of( 2023 , Month.NOVEMBER )
.plusMonths( 1 )
.atDay( 1 )
.atStartOfDay( ZoneId.of( "Asia/Kolkata" ) )
.toInstant()
.toEpochMilli()
Details
2023年9月
用java.time.YearMonth
级代表一个月.
YearMonth ym = YearMonth.of( 2023 , Month.NOVEMBER ) ;
特定时区中特定月份的开始和结束时间,特别是"亚洲/加尔各答"(UTC+05:30).
先拿到日期.
LocalDate startDate = ym.atDay ( 1 );
LocalDate endDate = ym.atEndOfMonth ( );
获得第一天的第一个时刻.这样做需要一个时区.不要假设一天从00:00开始,因为某些地区的某些日期可能从其他时间开始,例如01:00.让java.time决定一天中的第一个时刻.
ZoneId z = ZoneId.of ( "Asia/Kolkata" );
ZonedDateTime startZdt = startDate.atStartOfDay ( z );
完时间:2023-09-30 23:59:59
你的例子是错误的.如果你每个月都来月经,你会错过最后一天的最后一秒.
最好将你的时间跨度定义为半开放,其中开始是inclusive,结束是exclusive.因此,一个月从第一天的第一个时刻开始,一直到(但不包括)第following个月的第一个时刻.使用这种安排,你不会失go 最后一秒.
ZonedDateTime endZdt = endDate.plusDays ( 1 ).atStartOfDay ( z );
显然,您希望将这两个时刻表示为自UTC,1970-01-01T00:00Z中看到的1970年第一个时刻的纪元参考以来的毫秒数.
你试图让…伯爵
Timestamp.valueOf(istDateTime.toLocalDateTime()).getTime();
…在两个方面是不正确的:
- 您拨打了
toLocalDateTime
,它没有任何时区或与UTC的偏移量.在使用朋友圈时,不要使用LocalDateTime
个对象.有关更多说明,请参阅正确的Answer by Johnson-Pint.
- 您使用的是一个有严重缺陷的遗留类
Timestamp
,它在几年前就被JSR310中定义的现代java.time类所取代.避免使用遗留类,只使用java.time个类.
要将我们的两个时刻调整到与UTC的时间子午线的零时-分-秒的偏移量,提取Instant
个对象.
Instant startInstant = startZdt.toInstant ( );
Instant endInstant = endZdt.toInstant ( );
从那里你可以得到你的毫秒数.
long start = startInstant.toEpochMilli ( );
long end = endInstant.toEpochMilli ( );
我不建议你用这种方式来表现时刻.毫秒计数是模棱两可的,因为它只是一个没有上下文的整数,这造成了模棱两可.1970年01月01T00:00Z只是几十个common epoch references个中的一个.此外,人类无法破译来自纪元的计数.这意味着错误可能很容易逃脱注意.
我建议您使用标准的ISO 8601格式以文本形式传递日期-时间值.就像在UTC看到的那样,一个例子是2023-10-02T20:53:59Z
.T
将日期部分与时间部分分开.Z
是+00:00
的缩写,偏移量为零.
下面是一个完整的代码示例.
package work.basil.example;
import java.time.*;
public class MonthMoments
{
public static void main ( String[] args )
{
YearMonth ym = YearMonth.of ( 2023 , Month.NOVEMBER );
LocalDate startDate = ym.atDay ( 1 );
LocalDate endDate = ym.atEndOfMonth ( );
ZoneId z = ZoneId.of ( "Asia/Kolkata" );
ZonedDateTime startZdt = startDate.atStartOfDay ( z );
ZonedDateTime endZdt = endDate.plusDays ( 1 ).atStartOfDay ( z );
Instant startInstant = startZdt.toInstant ( );
Instant endInstant = endZdt.toInstant ( );
long start = startInstant.toEpochMilli ( );
long end = endInstant.toEpochMilli ( );
System.out.println ( "startZdt = " + startZdt );
System.out.println ( "endZdt = " + endZdt );
System.out.println ( "startInstant = " + startInstant );
System.out.println ( "endInstant = " + endInstant );
System.out.println ( "start = " + start );
System.out.println ( "end = " + end );
}
}
运行时:
startZdt = 2023-11-01T00:00+05:30[Asia/Kolkata]
endZdt = 2023-12-01T00:00+05:30[Asia/Kolkata]
startInstant = 2023-10-31T18:30:00Z
endInstant = 2023-11-30T18:30:00Z
start = 1698777000000
end = 1701369000000
为了处理成对的时刻,我建议将ThreeTen-Extra库添加到你的项目中.该库包括Interval
类,用于将一段时间表示为一对Instant
个对象.该类提供了几个方便的方法,如contains
、abuts
和intersection
.该类解析/生成标准ISO 8601格式的文本,两个时刻之间用斜杠隔开.
Interval monthInterval = Interval.of( startInstant , endInstant ) ;