我必须根据年,月,日,小时,分钟来计算次数。(秒统一为零,我不需要秒)
我选择HashMap作为数据结构。
HashMap<Calendar,Integer> arr_time;
如果已经有相同的时间(年,月,日,小时,分钟),我想增加Integer或添加一个新的时间(年,月,日,小时,分钟)。
Calendar calendar = Calendar.getInstance();
calendar.set(mYear,mMonth,mDay,mHour,mMinute,0);
if(arr_time.containsKey(calendar)){
// increase Integer value
// ++1;
}else{
// add new time
// arr_time.put(calendar,1);
}
我认为,如果年,月,日,小时和分钟相同,则可以识别相同的日历。 但这不是。
出什么问题了?
我没有使用“日期”。 这是因为Android Devloper这样说。
日期(int年,int月,int日期,int hrs,int min,int sec) 从API级别1开始不推荐使用此构造函数。从JDK 1.1版开始,由Calendar.set(year + 1900,month,date,hrs,min,sec)或GregorianCalendar(year + 1900,month,date,hrs,min,秒)。
答案 0 :(得分:1)
Calendar
可怕的Calendar
类在几年前被 java.time 类取代,特别是ZonedDateTime
。
您忽略了时区的关键问题。在您提供时区(或自UTC偏移)的上下文之前,日期和时间没有实际意义。例如,中午是Europe/Paris
,比Asia/Tokyo
中的中午要晚得多,并且比America/Montreal
中的中午要早得多。
ZonedDateTime
使用ZonedDateTime
类表示带有时区的日期和时间。
ZoneID
以Continent/Region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
truncatedTo
如果要将秒和小数秒都设置为零,请截断到分钟。
ZonedDateTime zdt = ZonedDateTime.now( z ).truncatedTo( ChronoUnit.MINUTES ) ; // Set the whole second and the fractional second both to zero.
LocalDateTime
如果出于计数目的,您只想考虑带日期的日期而忽略时区,请提取LocalDateTime
。 LocalDateTime
只是一个带有日期的日期,没有任何时区或从UTC偏移的概念。
LocalDateTime ldt = zdt.toLocalDateTime() ;
Map
➙SortedMap
➙TreeMap
手握LocalDateTime
,即可进行计数。制作一个Map
,其中键是LocalDateTime
,值是Integer
。
我想您会关心日期时间键的排序顺序,所以请使用SortedMap
。 TreeMap
就是这样一种实现。
SortedMap< LocalDateTime , Integer > map = new TreeMap() ;
对于每个LocalDateTime
,从Integer
中检索Map
对象。递增计数,然后用新的Integer
对象替换。
使用Map
已经在Stack Overflow上进行了数百次(甚至数千次)的讨论。因此,搜索是否需要更多讨论和示例。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
答案 1 :(得分:0)
Map<LocalDateTime, Integer> arr_time = new HashMap<>();
ZoneId zone = ZoneId.of("Antarctica/Vostok");
for (int i = 0; i < 10; i++) {
LocalDateTime now = LocalDateTime.now(zone).truncatedTo(ChronoUnit.MINUTES);
arr_time.compute(now, (ldt, oldCount) -> oldCount == null ? Integer.valueOf(1) : oldCount + 1);
TimeUnit.MILLISECONDS.sleep(103);
}
System.out.println(arr_time);
当我刚运行代码时,我得到了:
{2019-02-20T13:42 = 10}
我录制了10次,在两者之间睡觉以确保它们不完全相同。但是因为我每分钟都被删节,所以它们都以2019-02-20T13:42
的形式结束并被计算在内。
要根据LocalDateTime
个变量创建一个int
,
int mYear = 2019;
int mMonth = Calendar.JANUARY;
int mDay = 31;
int mHour = 23;
int mMinute = 45;
LocalDateTime ldt = LocalDateTime.of(mYear, mMonth + 1, mDay, mHour, mMinute);
System.out.println(ldt);
2019-01-31T23:45
由于您将mMonth
与Calendar
一起使用,因此我假设它是基于0的。 LocalDateTime
就像人类一样,从1开始数月,所以我需要加1。
calendar.set(mYear,mMonth,mDay,mHour,mMinute,0)
设置年,月,日,时,分和秒,但未设置毫秒。由于每个Calendar
对象都是用当前时间创建的,因此毫秒数通常会有所不同,因此即使您设置了相同的值,Calendar
对象仍然不相等。
6-arg set
方法的行为使很多人感到惊讶,并且在该类设计不良的许多点中只是次要点。您不应该使用它。自2014年以来,我们有了java.time,因此实际上没有理由。
是的,java.time在较新和较旧的Android设备上均可正常运行。它只需要至少 Java 6 。
org.threeten.bp
导入日期和时间类。java.time
。java.time
向Java 6和7(JSR-310的ThreeTen)的反向端口。