我有一种方法可以根据时区查找月份结束日期。
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("CET"));
calendar.set(
Calendar.DAY_OF_MONTH,
calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
);
System.out.println(calendar.getTime());`
它显示输出:Thu Aug 30 18:04:54 PDT 2018
。
但是,它应该给我CET的输出。
我想念什么?
答案 0 :(得分:4)
Calendar.getTime()
方法返回一个Date对象,然后将其打印在代码中。问题是Date
类不包含任何时区概念,即使您已通过Calendar.getInstance()
调用指定了时区。是的,的确令人困惑。
因此,要在特定时区中打印Date
对象,必须使用SimpleDateFormat类,在打印前必须在其中调用SimpleDateFormat.setTimeZone()
指定时区。
这是一个例子:
import java.util.Calendar;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
public class TimeZoneTest {
public static void main(String argv[]){
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("CET"));
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
System.out.println("calendar.getTime(): " + calendar.getTime());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("CET"));
System.out.println("sdf.format(): " + sdf.format(calendar.getTime()));
}
}
这是我计算机上的输出:
calendar.getTime(): Fri Aug 31 01:40:17 UTC 2018
sdf.format(): 2018-Aug-31 03:40:17 CEST
答案 1 :(得分:1)
这是因为Date对象的状态没有时区,并且getTime()
实际上返回一个与JVM时区相对应的日期,而您需要SimpleDateFormat进行格式化并在您所需的时区中打印日期。
如果尝试添加以下代码行,则可能会发现日历中的时区实际上是CET。
System.out.println(calendar.getTimeZone().getDisplayName());
答案 2 :(得分:1)
YearMonth // Represent a year-month without day-of-month.
.now( // Capture the current year-month as seen in the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Africa/Tunis" ) // Specify your desired time zone. Never use 3-4 letter pseudo-zones such as `CET`.
) // Returns a `YearMonth` object.
.atEndOfMonth() // Determine the last day of this year-month. Returns a `LocalDate` object.
.atStartOfDay( // Let java.time determine the first moment of the day. Not necessarily 00:00:00, could be 01:00:00 or some other time-of-day because of anomalies such as Daylight Saving Time (DST).
ZoneId.of( "Africa/Tunis" )
) // Returns a `ZonedDateTime` object, representing a date, a time-of-day, and a time zone.
您使用的是可怕的旧Calendar
类,该类早在几年前就被取代了,但是使用的是现代的 java.time 类。
LocalDate
如果仅需要日期,请使用LocalDate
类。然后,时区与您的输出无关。
但是时区与确定当前日期非常相关。在任何给定时刻,日期都会在全球范围内变化。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用3-4个字母的缩写,例如CET
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Europe/Paris" ) ; // Or "Africa/Tunis" etc.
LocalDate today = LocalDate.now( z ) ; // Capture the current date as seen by the wall-clock time used by the people of a certain region (a time zone).
YearMonth
获取该日期的月份。用YearMonth
代表一年月。
YearMonth ym = YearMonth.from( today ) ;
或者跳过LocalDate
。
YearMonth ym = YearMonth.now( z ) ;
月底结束
LocalDate endOfThisMonth = ym.atEndOfMonth() ;
要生成代表该String
对象值的LocalDate
,请调用toString
。默认格式取自ISO 8601标准。对于将是YYYY-MM-DD的仅日期值,例如2018-01-23
。
String output = endOfThisMonth.toString() ;
如果需要其他格式,请使用DateTimeFormatter
类。搜索堆栈溢出以获取许多示例和讨论。
如果需要一点时间,可以在LocalDate
中添加时间和时区以获得ZonedDateTime
。或者让ZonedDateTime
确定一天中的第一时刻(并非总是00:00:00!)。
ZonedDateTime zdt = LocalDate.atStartOfDay( z ) ;
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。