如何在java中获取选定月份的最后日期最后时间戳?

问题描述 投票:0回答:3

从下面的java代码中,我得到了一个月的第一个和最后一个日期时间戳,但在这里我需要最后一个日期时间戳为 - “Mon Aug 31 23:59:59 IST 2015”而不是 - “Mon Aug 31 00:00:00 IST 2015”?

        Calendar cal = Calendar.getInstance();
        int year = 2015;
        int month = 07;
        cal.set(cal.DATE,1);
        cal.set(cal.YEAR,year);
        cal.set(cal.MONTH, month);
        String firstDate = (cal.getActualMinimum(cal.DATE) + "/" + (month+1) + "/" +year);
        System.out.println("firstDate-->"+"\t"+firstDate);
        String lastDate = (cal.getActualMaximum(cal.DATE) + "/" + (month+1) + "/" +year);
        System.out.println("lastDate-->"+"\t"+lastDate);
        DateFormat firstFormat = new SimpleDateFormat("dd/MM/yyyy");
        Date beginDate = firstFormat.parse(firstDate);
        System.out.println("BeginDate Timestamp"+ "\t" + beginDate);
        DateFormat secoundFormat = new SimpleDateFormat("dd/MM/yyyy");
        Date endDate = secoundFormat.parse(lastDate);
        System.out.println("endDate Timestamp"+ "\t" + endDate);

输出:->

firstDate-->    1/8/2015
lastDate-->    31/8/2015
BeginDate Timestamp Sat Aug 01 00:00:00 IST 2015
endDate Timestamp   Mon Aug 31 00:00:00 IST 2015

如果我们有任何解决方案,请帮助我。

java
3个回答
0
投票

如果我理解你的问题,看起来你想将一年和一个月传递到一个方法中,并返回所传递的月份的最后一天。

我建议考虑(按此顺序):

  1. 你用的是哪个jdk
  2. 日历配置
  3. 时区配置(也许)
  4. 使用乔达时间

从 1.8 开始,jdk 中添加了许多类似 JodaTime 的功能,例如请参阅 https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html(如果您不使用 1.8,则可以使用 joda lib,假设您的组织允许)

Calendar.getInstance() 给出默认的 TimeZone 和默认的 Locale,这意味着 正在运行的 JVM 的定义。您可能需要也可能不需要考虑这一点,并且实现的不仅仅是 getInstance()。请参阅 API javadoc。

假设公历(嘿,你可能是巴哈伊历,一年有 19 个月......),这是一个使用 JDK 1.7、JodaTime jar 2.2、validation-1.0.0.GA jar 的部分实现:

@Test
public void testDate() {

    final String dateStringOfFirstDay = "1.7.2015";
    final Date lastDayOfMonth = getLastDayOfMonth(dateStringOfFirstDay);
    Assert.assertNotNull(lastDayOfMonth);
    //more assertions ...
}

private Date getLastDayOfMonth(@NotNull String dateStringOfFirstDay) {

    //further validation here necessary according to required date format 
    DateTime dt = DateTime.parse(dateStringOfFirstDay);
    return dt.dayOfMonth().withMaximumValue().toDate();
}

DateFormat/DateTimeFormat 的定义和进一步的结果断言由您决定。

祝你好运!


0
投票

伙计们,我的问题得到了解决方案! 我想这也会对你有帮助...

Calendar calendar = Calendar.getInstance();
        int year=2015;
        int month=7;
        int date=31;
        int hourOfDay=23;
        int minute=59;
        int second=59;
        int milliSecond=999;
        calendar.set(year, month, date, hourOfDay, minute, second);
        calendar.set(calendar.MILLISECOND, milliSecond);
        System.out.println("Time from Calendar: "+calendar.getTime());
        long timeInMilliSeconds=calendar.getTimeInMillis();
        System.out.println("timeInMilliSeconds from calendar: "+timeInMilliSeconds);
        Timestamp timestamp=new Timestamp(timeInMilliSeconds);
        System.out.println(timestamp);

上面的程序给出了选定月份的最后一个日期的最后时间戳。 getTimeInMillis() 获取从 1970 年 1 月 1 日到当前时间的时间(以毫秒为单位)。 使用这些毫秒我得到时间戳。 谢谢各位的帮助!!!

输出:->

Time from Calendar: Mon Aug 31 23:59:59 IST 2015
timeInMilliSeconds from calendar: 1441045799999
2015-08-31 23:59:59.999

0
投票

避免全封闭范围

你说:

我得到了一个月的第一个和最后一个日期时间戳,但在这里我需要最后一个日期时间戳为 - “Mon Aug 31 23:59:59 IST 2015”

不明智。您定义月份时间范围的方法被正式称为“完全封闭”,其中开始和结束都是“包含”的。这种方法留下了间隙,并使时间跟踪变得困难。 您的值“Mon Aug 31 23:59:59 IST 2015”不涵盖当天的最后一秒,23:59:59.000000001、23:59:59.000000002、…、23:59:59.999999999 以及最后一纳秒前往“Mon Sep 01 00:00:00 IST 2015”。 如果你试图将两个月的时间放在一起,你就会失败。每个月之间会有整整第二个间隙。该秒内发生的任何事件都将从您的搜索中省略。

半开

处理时间跨度的更好方法是

半开放

,其中开始是

包容

,而结束是排他 因此,在半开放方法中,一个月的定义如下。首先是开始。从一年中的月份开始,然后获取该月的第一个

日期

,并应用时区来确定时刻,即该时区中看到的当天的第一个时刻。 YearMonth yearMonth = YearMonth.of( 2015 , Month.AUGUST ) ; LocalDate firstOfMonth = yearMonth.atDay( 1 ) ; ZonedId z = ZoneId.of( "Asia/Kolkata" ) ; ZonedDateTime start = firstOfMonth.atStartOfDay( z ) ; 接下来,我们得到月底。在半开中,月份从该月第一天的第一时刻开始,一直到(但不包括)

月第一天的第一时刻。
注意,我们让 

java.time 确定一天开始的时间。永远不要假设一天是从 00:00 开始的。某些时区的某些日子从一天中的另一个时间开始,例如 01:00。

YearMonth nextYearMonth = yearMonth.plusMonths( 1 ) ; LocalDate firstOfNextMonth = nextYearMonth.atDay( 1 ) ; ZonedDateTime end = firstOfNextMonth.atStartOfDay( z ) ;

现在我们有两个时刻,月初和下个月的开始。这不会留下任何间隙。这种方法使相邻的时间段变得简单、清晰和完整。

Interval

为了表示这个时间跨度,您可以定义自己的

record

类。但我建议将

ThreeTen-Extra 库添加到您的项目中。然后访问它的

Interval 类。
org.threeten.extra.Interval
类将两个时刻的跨度表示为一对
java.time.Instant

对象。

Instant

 表示在 UTC 中看到的时刻,即与 UTC 的偏移为零时、分、秒。我们可以从 
Instant
 对象中提取 
ZonedDateTime
,有效地从我们选择的时区调整为 UTC。时间线上相同的点,但通过不同的挂钟/日历查看。
Interval interval = Interval.between( start.toInstant() , end.toInstant() ) ;
有了 
Interval

,您就可以调用有用的方法,如
contains

overlaps

abuts
 等。
java.time

请注意,上面的代码仅使用了 Java 8 及更高版本中内置的

java.time 类。

永远不要使用有严重缺陷的遗留日期时间类,例如

DateCalendar

DateFormat

SimpleDateFormat
	
© www.soinside.com 2019 - 2024. All rights reserved.