在Java中获取当前日期/时间的最佳方法是什么?
当前回答
Java 8或更高版本
LocalDateTime.now() and ZonedDateTime.now()
其他回答
创建日期对象并将其打印下来。
Date d = new Date(System.currentTimeMillis());
System.out.print(d);
这取决于您想要的日期/时间形式:
如果您希望日期/时间是一个单一的数值,那么System.currentTimeMillis()会给出该值,表示为UNIX纪元后的毫秒数(Java long)。该值是UTC时间点的增量,与本地时区1无关。如果您希望日期/时间以允许您以数字方式访问组件(年、月等)的形式显示,则可以使用以下选项之一:new Date()为您提供了一个用当前日期/时间初始化的Date对象。问题是DateAPI方法大多有缺陷。。。并且已弃用。Calendar.getInstance()使用默认的Locale和TimeZone为您提供一个用当前日期/时间初始化的Calendar对象。其他重载允许您使用特定的区域设置和/或时区。日历工作。。。但是API仍然很麻烦。neworg.joda.time.DateTime()为您提供了一个使用默认时区和年表用当前日期/时间初始化的joda时间对象。还有很多其他Joda替代品。。。太多了,这里无法描述。(但请注意,有些人报告Joda time存在性能问题。https://stackoverflow.com/questions/6280829.)在Java 8中,调用Java.time.LocalDateTime.now()和Java.time.ZonedDateTime.nnow()将为当前日期/时间提供表示2。
在Java8之前,大多数了解这些事情的人都推荐Joda time拥有(迄今为止)最好的JavaAPI来完成涉及时间点和持续时间计算的事情。
对于Java 8和更高版本,建议使用标准Java.time包。Joda时间现在被认为是“过时的”,Joda维护人员建议人们迁移。
1-System.currentTimeMillis()提供“系统”时间。虽然通常将系统时钟设置为(标称)UTC,但本地UTC时钟和真实UTC之间会存在差异(增量)。增量的大小取决于系统时钟与UTC同步的程度(以及频率)。2-请注意,LocalDateTime不包括时区。正如javadoc所说:“如果没有偏移量或时区等附加信息,它就不能表示时间线上的某个时刻。”注意:如果不迁移,Java8代码不会损坏,但Joda代码库最终可能会停止获取错误修复和其他补丁。截至2020-02年,Joda的官方“生命终结”尚未宣布,Joda API也未被标记为已弃用。
tl;博士
Instant.now() // Capture the current moment in UTC, with a resolution of nanoseconds. Returns a `Instant` object.
…或…
ZonedDateTime.now( // Capture the current moment as seen in…
ZoneId.of( "America/Montreal" ) // … the wall-clock time used by the people of a particular region (a time zone).
) // Returns a `ZonedDateTime` object.
java时间
一些答案提到java.time类是与最早版本的java捆绑在一起的麻烦的旧式日期时间类的现代替代品。以下是更多信息。
时区
其他答案未能解释时区对确定当前日期和时间的重要性。对于任何给定的时刻,日期和时间在全球各地因地区而异。例如,午夜过后几分钟,在法国巴黎是新的一天,而在魁北克省蒙特利尔,这一天仍然是“昨天”。
瞬间
作为最佳实践,您的大部分业务逻辑和数据存储/交换应该在UTC中完成。
要以纳秒为单位获得UTC中的当前时刻,请使用Instant类。传统的计算机硬件时钟精度有限,因此当前时刻可能以毫秒或微秒而不是纳秒为单位。
Instant instant = Instant.now();
区域日期时间
您可以将“即时”调整到其他时区。应用ZoneId对象以获取ZonedDateTime。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
我们可以跳过即时,直接获取当前的ZonedDateTime。
ZonedDateTime zdt = ZonedDateTime.now( z );
始终传递可选的时区参数。如果省略,则应用JVM的当前默认时区。默认值可以随时更改,即使在运行时也是如此。不要让你的应用受到你无法控制的外部因素的影响。始终指定所需/预期的时区。
ZonedDateTime do_Not_Do_This = ZonedDateTime.now(); // BAD - Never rely implicitly on the current default time zone.
您可以稍后从ZonedDateTime中提取Instant。
Instant instant = zdt.toInstant();
如果您需要时间线上的实际时刻,请始终使用Instant或ZonedDateTime,而不是LocalDateTime。“本地…”类型故意没有时区的概念,因此它们只代表一个可能时刻的粗略概念。要获得实际时刻,必须指定一个时区,以将Local…类型转换为ZonedDateTime,从而使其具有意义。
本地日期
LocalDate类表示一个仅日期的值,没有时间和时区。
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z ); // Always pass a time zone.
串
要生成表示日期时间值的字符串,只需对标准ISO 8601格式的java.time类调用toString。
String output = myLocalDate.toString(); // 2016-09-23
…或…
String output = zdt.toString(); // 2016-09-23T12:34:56.789+03:00[America/Montreal]
ZonedDateTime类通过在方括号中明智地附加时区名称来扩展标准格式。
对于其他格式,请在堆栈溢出中搜索DateTimeFormatter类上的许多问题和答案。
避免LocalDateTime
与RamanSB对该问题的评论相反,您不应将LocalDateTime类用于当前日期时间。
LocalDateTime故意缺少UTC信息的任何时区或偏移量。因此,当您跟踪时间线上的特定时刻时,这是不合适的。当然不适合捕捉当前时刻。
LocalDateTime只有日期和时间,例如“2020年1月23日中午”,但我们不知道这是日本东京的中午还是美国俄亥俄州托莱多的中午,两个不同的时刻相隔很多小时。
“本地”的措辞与直觉相悖。它意味着任何地点,而不是任何一个特定地点。例如,今年的圣诞节从12月25日午夜开始:2017-12-25T00:00,表示为LocalDateTime。但这意味着午夜在全球不同的时间点。午夜首先发生在基里巴斯,随后发生在新西兰,几个小时后发生在印度,依此类推,在法国,圣诞节开始前又过了几个小时,而加拿大的孩子们仍在等待这一天。这些圣诞起点中的每一个都将表示为单独的ZonedDateTime。
从系统外部
如果您不能信任系统时钟,请参阅Java:从服务器获取当前日期和时间,而不是系统时钟和我的答案。
java.time.Clock(java.time.Clock)
要利用当前时刻的替代供应商,请编写抽象java.time.Clock类的子类。
您可以将Clock实现作为参数传递给各种java.time方法。例如,Instant.now(时钟)。
Instant instant = Instant.now( yourClockGoesHere ) ;
出于测试目的,请注意Clock本身静态可用的Clock替代实现:固定、偏移、滴答等等。
关于java.time
java.time框架内置于Java8和更高版本中。这些类取代了麻烦的旧式日期时间类,如java.util.date、Calendar和SimpleDateFormat。
要了解更多信息,请参阅Oracle教程。并在Stack Overflow中搜索许多示例和解释。规范为JSR 310。
现在处于维护模式的Joda Time项目建议迁移到java.Time类。
您可以直接与数据库交换java.time对象。使用符合JDBC4.2或更高版本的JDBC驱动程序。不需要字符串,也不需要java.sql.*类。
从哪里获取java.time类?
Java SE 8、Java SE 9、Java SE 10、Java SE 11和更高版本—标准Java API的一部分,带有捆绑实现。Java9添加了一些小功能和修复。Java SE 6和Java SE 7大多数java.time功能在ThreeTen Backport中被向后移植到java 6和7。安卓java.time类的Android捆绑包实现的更高版本。对于早期的Android(<26),ThreeTenABP项目采用ThreeTen Backport(如上所述)。请参阅如何使用ThreeTenABP…。
ThreeTen Extra项目使用其他类扩展java.time。这个项目是未来可能添加java.time的试验场。您可以在这里找到一些有用的类,如Interval、YearWeek、YearQuarter等。
首先了解java.util.Date类
1.1如何获取当前日期
import java.util.Date;
class Demostration{
public static void main(String[]args){
Date date = new Date(); // date object
System.out.println(date); // Try to print the date object
}
}
1.2如何使用getTime()方法
import java.util.Date;
public class Main {
public static void main(String[]args){
Date date = new Date();
long timeInMilliSeconds = date.getTime();
System.out.println(timeInMilliSeconds);
}
}
这将返回自1970年1月1日00:00:00 GMT以来的毫秒数,用于时间比较。
1.3如何使用SimpleDateFormat类设置时间格式
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
class Demostration{
public static void main(String[]args){
Date date=new Date();
DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
String formattedDate=dateFormat.format(date);
System.out.println(formattedDate);
}
}
也可以尝试使用不同的格式模式,如“yyyy-MM-dd hh:MM:ss”,并选择所需的模式。http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
了解java.util.Calendar类
2.1使用日历类获取当前时间戳
import java.util.Calendar;
class Demostration{
public static void main(String[]args){
Calendar calendar=Calendar.getInstance();
System.out.println(calendar.getTime());
}
}
2.2尝试使用setTime和其他设置方法将日历设置为不同的日期。
资料来源:http://javau91.blogspot.com/
看看Date课程。还有一个更新的Calendar类,它是执行许多日期/时间操作的首选方法(许多date方法已被弃用)
如果您只想要当前日期,那么创建一个新的date对象或调用Calendar.getInstance();。
推荐文章
- 转换列表的最佳方法:map还是foreach?
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 新DateTime()与默认值(DateTime)
- 设计模式:工厂vs工厂方法vs抽象工厂