我有一些关于java Date类的问题,这让我很困惑。
我有两个问题:
我有一个日期对象,我想看看它中存储的日期是否晚于当天的开头?那么,如果它比今天早上00:00还要晚?
第二个问题是,我想按天分组几个日期对象。但同样,我不明白我应该如何检查是否在特定日期的24小时内。
我认为它们有点相关,一旦我有一个日期对象的'日',它就不会很难?
任何帮助都非常感谢,Date类让我很困惑..
答案 0 :(得分:1)
我有一个日期对象,我想看看它中存储的日期是否晚于当天的开头?那么如果它比今天早上00:00还要晚?
before
method进行比较。第二个问题是,我希望白天对几个日期对象进行分组。但同样,我不明白我应该如何检查它是否在特定日期的24小时内。
只按年,月和日期字段分组,或重置小时,分钟和秒字段。
答案 1 :(得分:1)
java Date / Calendar类实现得很差。
听起来你应该使用joda时间 - 特别是LocalDate。
http://joda-time.sourceforge.net/key_partial.html
http://joda-time.sourceforge.net/api-release/org/joda/time/LocalDate.html
这应解决#1和#2。
仅供参考 - JodaTime最终将取代JDK日期(jsr 310) 粗糙的分组解决方案:
public Map<LocalDate, List<Foo>> groupByDate(List<Foo> foos) {
Map<LocalDate, List<Foo>> groupedFoo = new HashMap()<..>
for(Foo foo : foos) {
Date javaDate = foo.getDate();
LocalDate jodaDate = new LocalDate(javaDate);
List<Foo> dateGroupedFoos = groupedFoo.get(jodaDate);
if (null == dateGroupedFoos) {
dateGroupedFoos = new ArrayList()<..>;
groupedFoo.put(jodaDate, dateGroupedFoos);
}
dateGroupedFoos.add(foo);
}
}
答案 2 :(得分:0)
所以,如果它比今天00:00或更晚
请注意,在某些日期的某些时区,该日期不会在00:00:00开始。夏令时(DST)等异常表示该日可能会在另一时间开始,例如01:00:00。
确定当天的开始需要一个日期。确定日期需要时区。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4个字母伪区域,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate
LocalDate
类表示没有时间且没有时区的仅限日期的值。
LocalDate today = LocalDate.now( z ) ;
ZonedDateTime
让java.time确定该日期的第一个时刻。指定ZoneId
以获取ZonedDateTime
对象。
ZonedDateTime todayStart = today.atStartOfDay( z ) ; // Determine the first moment of the day in a particular time zone.
我想查看存储在其中的日期是否晚于当天的开头?
使用比较方法isBefore
,isAfter
和isEqual
。
boolean isFuture = ! ( someZdt.isBefore( todayStart ) ) ; // A shorter way to say "is equal to or later" --> "is NOT before".
Map
&amp; Set
我想在白天对几个日期对象进行分组...我不明白我应该如何检查它是否在特定日期的24小时内。
首先,请记住,日子并不总是24小时。由于DST等异常,它们可能长达23或25小时,或者其他长度。
因此,如果您想按日期跟踪它们,请使用LocalDate
而非数小时。您可以查询ZonedDateTime
的每个LocalDate
。
使用Map
,仅将日期部分(LocalDate
)作为关键字,并将该日期的ZonedDateTime
个对象保存在Collection
中,例如Set
表示地图条目的值。
Map < LocalDate, Set < ZonedDateTime > > map = new HashMap <>( );
这是一个完整的示例代码片段。你可以run this code live at IdeOne.com。
Map < LocalDate, Set < ZonedDateTime > > map = new HashMap <>( );
Set < ZonedDateTime > set = null;
ZoneId z = ZoneId.of( "Africa/Tunis" );
LocalDate today = LocalDate.now( z );
ZonedDateTime todayStart = today.atStartOfDay( z ); // Determine the first moment of the day in a particular time zone.
map.putIfAbsent( todayStart.toLocalDate( ) , new HashSet <>( ) );
set = map.get( todayStart.toLocalDate( ) ) ;
set.add( todayStart );
ZonedDateTime zdt1 = todayStart.plusHours( 6 );
map.putIfAbsent( zdt1.toLocalDate( ) , new HashSet <>( ) );
set = map.get( zdt1.toLocalDate( ) ) ;
set.add( zdt1 );
ZonedDateTime zdt2 = todayStart.plusDays( 2 );
map.putIfAbsent( zdt2.toLocalDate( ) , new HashSet <>( ) );
set = map.get( zdt2.toLocalDate( ) ) ;
set.add( zdt2 );
ZonedDateTime zdt3 = todayStart.plusMonths( 4 );
map.putIfAbsent( zdt3.toLocalDate( ) , new HashSet <>( ) );
set = map.get( zdt3.toLocalDate( ) ) ;
set.add( zdt3 );
System.out.println( "map.toString(): " + map );
我们希望在地图中看到3个条目,其中一个值是一组两个项目,而其他两个值是每个项目的一组。仔细阅读此输出,因为HashSet
不按照放置顺序返回项目。
map.toString():{2018-01-25 = [2018-01-25T00:00 + 01:00 [非洲/突尼斯]],2018-01-23 = [2018-01-23T00:00+ 01:00 [非洲/突尼斯],2018-01-23T06:00 + 01:00 [非洲/突尼斯],2018-05-23 = [2018-05-23T00:00 + 01:00 [非洲/突尼斯] ]}
为了清楚起见,让我们分开。我们看到1月23日有一对价值,而1月25日和5月23日都有一个。
2018年1月25日= [2018-01-25T00:00 + 01:00 [非洲/突尼斯]]
2018-01-23 = [2018-01-23T00:00 + 01:00 [非洲/突尼斯],2018-01-23T06:00 + 01:00 [非洲/突尼斯]],
2018年5月23日= [2018-05-23T00:00 + 01:00 [非洲/突尼斯]]
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?