我在创建方法时遇到了以下问题:unix时间戳和表示获取第一个日期的时间段的int传入,该方法返回一个unix时间戳表示那个时候的第一天。我现在使用的方法使用Calendar类,如下所示:
public static long firstTime(long in, int period){
if(period == DAY_OF_FIVE_YEARS){
period = Calendar.DAY_OF_YEAR;
in -= in%Vars.FIVE_YEARS;
}
cal.setTimeInMillis(in*1000L);
cal.set(period,cal.getActualMinimum(period));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
return cal.getTimeInMillis()/1000L;
}
然而,有时我需要获得五年的第一天。例如,我将在1987年的一个日期通过,我希望这个方法能够在1985年的第一天返回。第一个if语句就是我的尝试,但它不起作用,而且我是想知道是否有更简单的方法。请注意,DAY_OF_FIVE_YEARS是一个表示它的int,而Vars.FIVE_YEARS是一个long,即五年内的秒数。
答案 0 :(得分:1)
感谢ajb,这里有一个方法可以找到几年的第一个倍数:
public static final int DAY_OF_FIVE_YEARS = 843521; //just any unused number
public static long firstTime(long in, int period){
cal.setTimeInMillis(in*1000L);
if(period == DAY_OF_FIVE_YEARS){
int year = cal.get(Calendar.YEAR);
cal.roll(Calendar.YEAR, -(year%5));
period = Calendar.DAY_OF_YEAR;
}
cal.set(period,cal.getActualMinimum(period));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
return cal.getTimeInMillis()/1000L;
}
答案 1 :(得分:1)
LocalDate // Represent a date-only value, without time-of-day and without time zone.
.of( 2018 , Month.JANUARY , 23 ) // Get a particular date.
.withDayOfYear( 1 ) // Get first of the year.
.minusYears( 1 ) // Go back a year
您正在滥用日期时间类,显然是试图在“带日期的日期和时区的日期”类中表示仅日期的值。
Vars.FIVE_YEARS是一个长整数,表示五年内的秒数
您将五年表示为秒数的概念在两个方面存在缺陷:(a)天并不总是24小时长,并且(b)年并不总是365天长。
另一个问题:您应该在日期时间对象中工作,而不是传递仅以毫秒为单位的整数。这些数字使调试和记录变得困难,因为人类无法理解其含义。因此,错误和错误可能会引起注意。如上所述,这些数字可能无法正确表示预期值。
您正在使用的是可怕的旧日期时间类,而这些类早已被 java.time 类取代。
Instant
将自纪元以来的毫秒数解析为Instant
。
Instant instant = Instant.ofEpochMilli( myMillis ) ;
时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,Paris France午夜之后的几分钟是新的一天,而Montréal Québec仍然是“昨天”。
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
LocalDate
LocalDate
类表示没有日期和时区的仅日期值。
从上面的ZonedDateTime
中提取日期。
LocalDate ld = zdt.toLocalDate() ;
如果您想要一年的第一天,请提出要求。
LocalDate firstOfThisYear = ld.withDayOfYear( 1 ) ; // Get first of the year.
根据需要回溯许多年。
LocalDate firstOfLastYear = ld.minusYears( 1 ) ;
如果要使用十年的前半年或下半年(0-4和5-9年),请选择年份并进行数学计算。
int year = ld.getYear() ; // Ex: 2018
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。