示例(如“ dd.MM.yyyy HH:mm”)。
java.util.Date开始= 21.01.2018 00:00
java.util.Date结束= 20.03.2018 00:00
我想创建java.util.List<MonthInterval> list
,例如:
我的课:
class MonthInterval {
Date monthBegin, monthEnd;
}
我试图自己做。但是,在java.util.Calendar
类中,我不了解如何计算今年这一月或另一个月的天数。但是我想我走错了路。有什么想法吗?
答案 0 :(得分:1)
您应该真正使用java.time
API,其中有些有趣的东西,使用
class MonthInterval {
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
LocalDateTime monthBegin, monthEnd;
public MonthInterval(LocalDateTime monthBegin, LocalDateTime monthEnd) {
this.monthBegin = monthBegin;
this.monthEnd = monthEnd;
}
@Override
public String toString() {
return monthBegin.format(formatter) + " > " + monthEnd.format(formatter);
}
}
您可以采用其他方式,例如
使用do-while loop
static List<MonthInterval> list(LocalDateTime begin, LocalDateTime end) {
List<MonthInterval> list = new ArrayList<>();
LocalDateTime nextDayMonth;
do {
nextDayMonth = begin.plusMonths(1).withDayOfMonth(1);
list.add(new MonthInterval(begin, nextDayMonth));
begin = nextDayMonth;
} while (nextDayMonth.getMonthValue() != end.getMonthValue());
list.add(new MonthInterval(begin, end));
return list;
}
具有for-i
循环
static List<MonthInterval> list(LocalDateTime begin, LocalDateTime end) {
List<MonthInterval> list = new ArrayList<>();
LocalDateTime nextDayMonth;
for (int i = 0; i < ChronoUnit.MONTHS.between(begin, end) + 1; i++) {
nextDayMonth = begin.plusMonths(1).withDayOfMonth(1);
list.add(new MonthInterval(begin, nextDayMonth));
begin = nextDayMonth;
}
list.add(new MonthInterval(begin, end));
return list;
}
用作
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
public static void main(String[] args) {
LocalDateTime begin = LocalDateTime.parse("21.01.2018 00:00", formatter);
LocalDateTime end = LocalDateTime.parse("20.03.2018 00:00", formatter);
list(begin, end).forEach(System.out::println);
}
// And get
21.01.2018 00:00 > 01.02.2018 00:00
01.02.2018 00:00 > 01.03.2018 00:00
01.03.2018 00:00 > 20.03.2018 00:00
答案 1 :(得分:1)
Interval.of(
LocalDateTime.parse( // Represent a date and a time-of-day but lacking a time zone or offset-from-UTC. So *not* a moment.
"21.01.2018 00:00" ,
DateTimeFormatter.ofPattern( "dd.MM.uuuu HH:mm" ) // Specify formatting pattern to match input strings.
) // Returns a `LocalDateTime` object.
.atZone( // Apply a time zone to determine a moment.
ZoneId.of( "Pacific/Auckland" ) // Always use proper time zone in `Continent/Region` format, never 2-4 letter codes such as `IST` or `EST` or `PST`.
) // Returns a `ZonedDateTime` object.
.toInstant() , // Convert from a `ZonedDateTime` object to a `Instant` to adjust into UTC.
… // Do the same as the above (the starting point) but for the stopping point.
) // Returns a `org.threeten.extra.Interval` object.
.toString() // Generate text representing both moments of this interval in standard ISO 8601 format, delimited by a `/` SOLIDUS character.
请勿使用java.util.Date
。可怕的类是几年前被现代的 java.time 类取代的。
other Answer by azro朝着正确的方向前进。但是,您无需发明自己的间隔类。查看在ThreeTen-Extra项目中找到的现有的经过验证的类。该项目由同一人Stephen Colebourne领导,他领导了JSR 310 java.time 项目和 Joda-Time 项目。
在 ThreeTen-Extra 库中,您将找到两个类来表示附加到时间轴上的时间跨度。
Interval
—在UTC中的一对时刻,Instant
个对象。 LocalDateRange
—一对仅日期的值,LocalDate
对象。如果您要说的是瞬间,请在LocalDateTime
对象处解析输入字符串。这不是不是时刻,只有潜在时刻,因为它们缺少时区或从UTC偏移。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd.MM.uuuu HH:mm" ) ;
LocalDateTime ldt = LocalDateTime.parse( "21.01.2018 00:00" , f ) ;
通过分配时区来确定实际时刻,以赋予LocalDateTime
真实的含义。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
通过提取Instant
调整为UTC。 Instant
代表时刻始终是UTC。
Instant instant = zdt.toInstant() ;
传递一对这样的Instant
对象以获得Interval
。
org.threeten.extra.Interval interval = Interval.of( start , stop ) ;
您可以将Interval
对象与方便的方法进行比较,例如isBefore
,isAfter
,overlaps
,contains
,encloses
等
如果您只关注日期而不是时间,请使用LocalDateRange
。我们仍然必须如上所述处理您的输入,因为任何给定时刻的日期在全球范围内都不同。例如,法国巴黎午夜后的几分钟是“明天”,而在蒙特利尔魁北克仍然是“昨天”。
对于日期,请使用上面看到的ZonedDateTime
对象并提取LocalDate
。
LocalDate ld = zdt.toLocalDate() ; // Extract the date as seen at that moment through the wall-clock time used by the people of that region (that time zone).
用这样的日期制作一个LocalDateRange
org.threeten.extra.LocalDateRange ldr = LocalDateRange.of( start , stop ) ;
类似于Interval
,LocalDateRange
类提供了方便的比较方法,例如overlaps
,contains
等。
21.01.2018 00:00-01.02.2018 00:00(或31.01.2018 23:59:59)
否,请不要在最后可能的时刻之前定义时间范围。那是尴尬和成问题的。一个问题是无限可分的小数秒。
相反,请使用 Half-Open 方法:开头是 inclusive ,而结尾是 exclusive 。
Search Stack Overflow了解更多信息。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。