希望以“dd / MM / yyyy HH:mm:ss.SS”格式显示当前日期和时间
我使用以下代码以“dd / MM / yyyy HH:mm:ss.SS”格式获取日期。
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class DateAndTime{ public static void main(String[] args)throws Exception{ Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS"); String strDate = sdf.format(cal.getTime()); System.out.println("Current date in String Format: "+strDate); SimpleDateFormat sdf1 = new SimpleDateFormat(); sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS"); Date date = sdf1.parse(strDate); System.out.println("Current date in Date Format: "+date); } }
并得到以下输出
Current date in String Format: 05/01/2012 21:10:17.287 Current date in Date Format: Thu Jan 05 21:10:17 IST 2012
请建议我应该怎样做以相同的字符串格式显示日期(日/月/日yH:mm:ss.SS),即我想要以下输出:
Current date in String Format: 05/01/2012 21:10:17.287 Current date in Date Format: 05/01/2012 21:10:17.287
请建议
你不能 – 因为你正在调用Date.toString()
,如果它是默认语言环境的默认日期格式,它将始终包含系统时区。 Date
值本身没有格式的概念。 如果你想以特定的方式格式化它,使用SimpleDateFormat.format()
…使用Date.toString()
几乎总是一个坏主意。
的SimpleDateFormat
sdf=new SimpleDateFormat("dd/MM/YYYY hh:mm:ss"); String dateString=sdf.format(date);
它将按预期给出输出28/09/2013 09:57:19
。
如需完整计划,请点击此处
以下代码给出了预期的输出。 你想要的吗?
import java.util.Calendar; import java.util.Date; public class DateAndTime { public static void main(String[] args) throws Exception { Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS"); String strDate = sdf.format(cal.getTime()); System.out.println("Current date in String Format: " + strDate); SimpleDateFormat sdf1 = new SimpleDateFormat(); sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS"); Date date = sdf1.parse(strDate); String string=sdf1.format(date); System.out.println("Current date in Date Format: " + string); } }
使用:
System.out.println("Current date in Date Format: " + sdf.format(date));
第一个打印行中的输出正在使用您的格式化程序。 第二个输出(从解析后的字符串创建的日期)使用Date#toString输出,它根据自己的规则进行格式化。 也就是说,你没有使用格式化程序。
规则根据您在此处看到和描述的内容: http : //docs.oracle.com/javase/6/docs/api/java/util/Date.html#toString ()
TL;博士
- 使用现代java.time类。
- 永远不要使用
Date
/Calendar
/SimpleDateFormat
类。
例:
ZonedDateTime // Represent a moment as seen in the wall-clock time used by the people of a particular region (a time zone). .now( // Capture the current moment. ZoneId.of( "Africa/Tunis" ) // Always specify time zone using proper `Continent/Region` format. Never use 3-4 letter pseudo-zones such as EST, PDT, IST, etc. ) .truncatedTo( // Lop off finer part of this value. ChronoUnit.MILLIS // Specify level of truncation via `ChronoUnit` enum object. ) // Returns another separate `ZonedDateTime` object, per immutable objects pattern, rather than alter (“mutate”) the original. .format( // Generate a `String` object with text representing the value of our `ZonedDateTime` object. DateTimeFormatter.ISO_LOCAL_DATE_TIME // This standard ISO 8601 format is close to your desired output. ) // Returns a `String`. .replace( "T" , " " ) // Replace `T` in middle with a SPACE.
java.time
现代方法使用java.time类, 这些类在几年前取代了可怕的旧日期时间类,如Calendar
和SimpleDateFormat
。
想要当前的日期和时间
使用Instant
捕获UTC中的当前时刻。
Instant instant = Instant.now() ;
要通过特定区域(时区)人员使用的挂钟时间镜头查看同一时刻,请应用ZoneId
以获取ZonedDateTime
。
以continent/region
的格式指定适当的时区名称 ,例如America/Montreal
, Africa/Casablanca
或Pacific/Auckland
。 切勿使用3-4字母缩写,例如EST
或IST
因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ; ZonedDateTime zdt = instant.atZone( z ) ;
或者,作为快捷方式,将ZoneId
传递给ZonedDateTime.now
方法。
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" ) ) ;
java.time类使用纳秒的分辨率。 这意味着最多九位小数的秒数。 如果只需要三毫秒,则截断 。 将您想要的限制作为ChronoUnit
枚举对象传递。
ZonedDateTime .now( ZoneId.of( "Pacific/Auckland" ) ) .truncatedTo( ChronoUnit.MILLIS )
在“dd / MM / yyyy HH:mm:ss.SS”格式中
我建议在生成字符串时始终包括从UTC或时区的偏移,以避免歧义和误解。
但是,如果您坚持,则可以在生成表示日期时间值的字符串时指定特定格式。 内置的预定义格式化程序几乎可以满足您所需的格式,但对于需要空格的T
。
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) .replace( "T" , " " ) ;
sdf1.applyPattern(“dd / MM / yyyy HH:mm:ss.SS”);
日期日期= sdf1.parse(strDate);
切勿使用用于呈现给人类的文本来交换日期时间值。
相反,请使用ISO 8601中为此目的定义的标准格式。
在解析/生成字符串时, java.time默认使用这些ISO 8601格式。
在交换特定时刻时,始终包括与UTC或时区的偏移量的指示符。 因此,为避免数据交换,应避免使用上面讨论的所需格式。 此外,通常最好将时刻换成UTC。 这意味着在java.time中使用Instant
。 您可以从ZonedDateTime
交换Instant
,有效地从时区调整到UTC,同一时刻,时间线上的相同点,但是不同的挂钟时间。
Instant instant = zdt.toInstant() ; String exchangeThisString = instant.toString() ;
2018-01-23T01:23:45.123456789Z
此ISO 8601格式在末尾使用Z
表示UTC,发音为“Zulu”。
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.Date
, Calendar
和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。
您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC驱动程序 。 不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
- Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11及更高版本 – 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和Java SE 7
- 大多数java.timefunction都在ThreeTen- Backport中反向移植到Java 6和7。
- Android的
- 更高版本的Android捆绑java.time类的实现。
- 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如Interval
, YearWeek
, YearQuarter
等。
免责声明:这个答案并不支持Date
类的使用(事实上它已经过时且设计不佳,所以我宁愿完全劝阻它)。 我尝试用格式回答有关日期和时间对象的定期重复问题。 为此,我使用Date
类作为示例。 其他课程在最后处理。
你不想
您不希望具有特定格式的Date
。 除了最简单的丢弃程序之外,其他所有程序的良好实践是使您的用户界面与您的模型和业务逻辑区分开来。 Date
对象的值属于您的模型,因此请将Date
保留在那里,绝不让用户直接看到它。 当你坚持这一点时, Date
格式永远不会重要。 每当用户看到日期时,将其格式化为String
并向用户显示该字符串。 同样,如果您需要特定格式的持久性或与其他系统交换,请将Date
格式化为字符串以实现此目的。 如果用户需要输入日期和/或时间,请接受字符串或使用日期选择器或时间选择器。
特例:存储到SQL数据库中。 您的数据库可能看起来需要特定的格式。 不是这样。 使用yourPreparedStatement.setObject(yourParamIndex, yourDateOrTimeObject)
,其中yourDateOrTimeObject
是LocalDate
, Instant
, LocalDateTime
或java.time中适当的日期时间类的实例。 再次不要担心该对象的格式。 搜索更多详细信息。
你不能
没有Date
,因为没有格式。 这是一个时间点,仅此而已。 一个有价值的容器。 在您的代码中, sdf1.parse
将您的字符串转换为Date
对象,即转换为某个时间点。 它不保留字符串,也不保留字符串中的格式。
要完成这个故事,让我们看一下代码中的下一行:
System.out.println("Current date in Date Format: "+date);
为了执行+
符号所需的字符串连接,Java需要首先将Date
转换为String
。 它通过调用Date
对象的toString
方法来完成此操作。 Date.toString
总是生成一个字符串,如Thu Jan 05 21:10:17 IST 2012
。 你无法改变它(除了在Date
的子类中,但你不想这样)。 然后,生成的字符串与字符串文字连接,以生成由System.out.println
打印的字符串。
简而言之,“格式”仅适用于日期的字符串表示,而不适用于日期本身。
Date没有格式是不是很奇怪?
我认为我所写的内容完全符合我们的期望。 它与其他类型相似。 想想一个int
。 可以将相同的int
格式化为字符串,如53,551
(点为千位分隔符), 00053551
, +53 551
或甚至0x0000_D12F
。 所有这些格式都会产生字符串,而int
只保持不变并且不会改变其格式。 使用Date
对象时它完全相同:您可以将其格式化为许多不同的字符串,但Date
本身始终保持不变。
我可以使用我选择的格式的LocalDate,ZonedDateTime,Calendar,GregorianCalendar,XMLGregorianCalendar,java.sql.Date,Time或Timestamp吗?
不,你不能,并且出于与上述相同的原因。 所提到的课程,实际上没有我见过的日期或时间课程都没有格式。 您只能在日期时间对象之外的String
中使用所需的格式。
链接
- 维基百科上的模型 – 视图 – 控制器
- 关于Jon Skeet编码博客上的java.util.Date
- Basil Bourque的答案解释了要做什么(也使用更现代的程序,比
Date
更友好的程序员)