在Java中生成两个日期之间的日期开始日期和日期结束时间。节日问题

时间:2015-06-04 05:43:27

标签: java date datetime calendar

我必须在两个日期之间产生天数。例如:

1420090495000 - > 2015年1月1日

1430458495000 - > 2015年5月1日

我必须为所有日子生成时间戳,例如

2015年1月1日00:00:00 - 2015年1月1日23:59:59

2015年1月2日00:00:00 - 2015年1月2日23:59:59

2015年1月3日00:00:00 - 2015年1月3日23:59:59

等等

我能够做到这一点。但是我在日光节省问题上遇到了一些问题。在三月的某个地方它正在产生这样的

2015年3月8日00:00:00 - 2015年3月9日00:01:00 哪个错了,应该像 2015年3月8日00:00:00 - 2015年3月8日23:59:59

我发现它是因为白天节省光的问题。如何解决这个问题?

我的代码是:

public static List<String> getDatesRange(long start, long end, String tzOffset) {
//tzOffset is 420. for USA

        TimeZone tz = TimeZone.getTimeZone(tzOffset);

        List<String> dates=new ArrayList();
        Calendar calendar = Calendar.getInstance(tz);

        calendar.set(Calendar.DAY_OF_WEEK, 1);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);


        while (start<end) {
            calendar.setTimeInMillis(start);
            long startTime = calendar.getTimeInMillis();
            int year= calendar.getWeekYear();


            long endTime = start + (1 * 24 * 3600 * 1000L);

            if(endTime<end) {
                endTime-=1000;
                System.out.println("Start Date= " + new Date(new Timestamp(start).getTime())+" ("+startTime+"), End Date= "+new Date(new Timestamp(endTime).getTime())+"("+endTime+")");

dates.add(startTime+"-"+endTime);
                start= endTime+1000;
            }
            else{
                System.out.println("Start Date= " + new Date(new Timestamp(start).getTime()) + " (" + startTime + "), End Date= " + new Date(new Timestamp(end).getTime()) + "(" + end + ")");
                start=end;
                dates.add(startTime+"-"+end);
            }
        }
        return dates;
    }

2 个答案:

答案 0 :(得分:1)

问题是您想要打印没有时区概念的日期(尽管开始日期取决于tzOffset参数)。如果您使用Java 8,则新的Java时间API具有专门为其设计的类:LocalDate

因此,您可以通过首先根据时间戳和时区确定开始日和结束日来完成您的方法,然后摆脱所有时区考虑因素。要打印范围,您可以通过在格式化程序中硬编码开始/结束时间来“欺骗”。

public static List<String> getDatesRange(long start, long end, String tzOffsetMinutes) {
  Instant startInstant = Instant.ofEpochMilli(start);
  Instant endInstant = Instant.ofEpochMilli(end);

  int offsetSeconds = Integer.parseInt(tzOffsetMinutes) * 60;
  ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSeconds);
  LocalDate startDate = OffsetDateTime.ofInstant(startInstant, offset).toLocalDate();
  LocalDate endDate = OffsetDateTime.ofInstant(endInstant, offset).toLocalDate();

  List<String> dates = new ArrayList<> ();
  DateTimeFormatter fmt = DateTimeFormatter.ofPattern(
                                         "MMM d, yyyy 00:00:00 - MMM d, yyyy 23:59:59");

  for (LocalDate d = startDate; !d.isAfter(endDate); d = d.plusDays(1)) {
    dates.add(fmt.format(d));
  }
  return dates;
}

您可以使用Calendars做类似的事情。

答案 1 :(得分:1)

我想知道有几件事情:

  • 为什么要使用Longs来定义日期?
  • 为什么要返回字符串列表而不是日期列表?
  • 为什么在这种情况下要考虑时区?

尽管如此,您只需使用日历和SimpleDateFormat即可实现此目的,如下所示:

public static Calendar getDayStart(final long timeInMillis) {
    final Calendar cal = Calendar.getInstance();
    // end time as a date
    cal.setTimeInMillis(timeInMillis);

    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);

    return cal;
}

public static List<String> getDatesRange(final long start, final long end) {

    final Calendar cal = getDayStart(start);
    final Date startDate = cal.getTime();

    final Calendar calEnd = getDayStart(end);
    //adding one day because of the strict comparison in the while below
    calEnd.add(Calendar.DAY_OF_YEAR, 1);
    final Date endDate = calEnd.getTime();

    final SimpleDateFormat formatter = new SimpleDateFormat("MMM d, yyyy HH:mm:ss");

    final List<String> dates = new ArrayList<String>();
    final Date dayEnd;
    String currentDay = "";

    while(cal.getTime().before(endDate)) {
        currentDay = formatter.format(cal.getTime());
        currentDay += " - ";
        //going to the end of the day
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.add(Calendar.SECOND, -1);
        currentDay += formatter.format(cal.getTime());
        //going to next day again and continue the loop
        cal.add(Calendar.SECOND, 1);
        //add what we computed to the list of days
        dates.add(currentDay);
    }

    return dates;
}