Ant*_*ith 21 java date jodatime
我在一个项目中工作,我在Date中有两种类型.我想计算这两个日期之间的周数.日期可能是不同的年份.对此有什么好的解决方案吗?
我试图用其他主题中提出的Joda-time来实现这一点.
我不熟悉这个库,但我尝试做这样的事情:
public static int getNumberOfWeeks(Date f, Date l){
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(f);
c2.setTime(l);
DateTime start = new DateTime(c1.YEAR, c1.MONTH, c1.DAY_OF_MONTH, 0, 0, 0, 0);
DateTime end = new DateTime(c2.YEAR, c2.MONTH, c2.DAY_OF_MONTH, 0, 0, 0, 0);
Interval interval = new Interval(start, end);
Period p = interval.toPeriod();
return p.getWeeks();
}
Run Code Online (Sandbox Code Playgroud)
但这完全错了......有什么建议吗?
nan*_*sen 34
joda时间非常简单:
DateTime dateTime1 = new DateTime(date1);
DateTime dateTime2 = new DateTime(date2);
int weeks = Weeks.weeksBetween(dateTime1, dateTime2).getWeeks();
Run Code Online (Sandbox Code Playgroud)
Tec*_*rip 27
更新Java 8帐户的答案
// TechTrip - ASSUMPTION d1 is earlier than d2
// leave that for exercise
public static long getFullWeeks(Calendar d1, Calendar d2){
Instant d1i = Instant.ofEpochMilli(d1.getTimeInMillis());
Instant d2i = Instant.ofEpochMilli(d2.getTimeInMillis());
LocalDateTime startDate = LocalDateTime.ofInstant(d1i, ZoneId.systemDefault());
LocalDateTime endDate = LocalDateTime.ofInstant(d2i, ZoneId.systemDefault());
return ChronoUnit.WEEKS.between(startDate, endDate);
}
Run Code Online (Sandbox Code Playgroud)
Bas*_*que 12
ChronoUnit
.WEEKS
.between(
myJavaUtilDate_Start.toInstant().atZone( ZoneId.of( "Asia/Tokyo" ) ) ,
myJavaUtilDate_Stop.toInstant().atZone( ZoneId.of( "Asia/Tokyo" ) )
)
Run Code Online (Sandbox Code Playgroud)
7
该java.time框架是建立在Java 8和更高版本。这些新类取代了与最早版本的 Java 捆绑在一起的旧日期时间类。
该java.time类也取代了非常成功的乔达时间框架。无论java.time和乔达时间由领导斯蒂芬Colbourne。
Instant 替换 java.util.Date现代类Instant取代了遗留类java.util.Date。两者都代表 UTC 中的一个时刻,即时间线上的一个特定点。自 UTC 中 1970 年第一时刻的同一纪元参考 1970-01-01T00:00Z 起,两者在内部都使用计数。旧类使用毫秒计数,而Instant使用更精细的纳秒计数。
要进行转换,请调用添加到旧类中的新方法。
Instant start = myJavaUtilDateStart.toInstant() ;
Instant stop = myJavaUtilDateStop.toInstant() ;
Run Code Online (Sandbox Code Playgroud)
让我们用一些示例值来具体说明。
Instant start = OffsetDateTime.of( 2020 , 1 , 23 , 15 , 30 , 0 , 0 , ZoneOffset.UTC ).toInstant();
Instant stop = OffsetDateTime.of( 2020 , 1 , 23 , 15 , 30 , 0 , 0 , ZoneOffset.UTC ).plusWeeks(7 ).toInstant();
Run Code Online (Sandbox Code Playgroud)
我们的两个Instant对象都代表一个时刻。目标是计算周数。Weeks 表示天,days 表示日历上的某些日期。
所以我们有点不匹配。对于任何给定时刻,日期在全球各地因时区而异。法国巴黎午夜过后的几分钟是一个新的约会。与此同时,在魁北克省蒙特利尔,落后几个小时,同一时刻仍然是“昨天”,也就是日历上的前一天。所以我们不能直接从一对矩计算周数。
您必须首先确定您希望为那些时刻感知日历的时区。
以、、 或等格式指定正确的时区名称。永远不要使用 2-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。Continent/RegionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST
ZoneId z = ZoneId.of( "America/Montreal" ) ;
Run Code Online (Sandbox Code Playgroud)
ZonedDateTime将此ZoneId应用于我们的Instant对象以调整到时区,产生一对ZonedDateTime对象。
ZonedDateTime startZdt = start.atZone( z ) ;
ZonedDateTime stopZdt = stop.atZone( z ) ;
Run Code Online (Sandbox Code Playgroud)
ChronoUnit.WEEKS现在我们可以使用ChronoUnit枚举来计算经过的周数。
长周 = ChronoUnit.WEEKS.between( startZdt , stopZdt );
转储到控制台。
System.out.println( "start.toString() = " + start );
System.out.println( "stop.toString() = " + stop );
System.out.println( "startZdt.toString() = " + startZdt );
System.out.println( "stopZdt.toString() = " + stopZdt );
System.out.println( "weeksCount: " + weeksCount );
Run Code Online (Sandbox Code Playgroud)
start.toString() = 2020-01-23T15:30:00Z
stop.toString() = 2020-03-12T15:30:00Z
startZdt.toString() = 2020-01-23T10:30-05:00[美国/蒙特利尔]
stopZdt.toString() = 2020-03-12T11:30-04:00[美国/蒙特利尔]
周数:7
该ThreeTen-EXTRA项目将功能添加到java.time内置到Java 8和更高版本的框架。
Weeks 班级该项目包括一个Weeks表示周数的类。它不仅可以计算,还可以在您的代码中用作类型安全对象。这种使用还有助于使您的代码自记录。
您可以通过为该Weeks.between方法提供一对时间点来实例化。这些时间点可以是任何实现java.time.temporal.Temporal 的东西,包括Instant, LocalDate, OffsetDateTime, ZonedDateTime, Year, YearMonth, 等等。
您的java.util.Date对象可以轻松转换为Instant对象,UTC 时间轴上的时刻,分辨率为纳秒。查看添加到旧日期时间类的新方法。要从 Date 转到 Instant,请调用java.util.Date::toInstant.
Weeks weeks = Weeks.between( startZdt , stopZdt );
Run Code Online (Sandbox Code Playgroud)
您可以询问周数。
int weeksNumber = weeks.getAmount(); // The number of weeks in this Weeks object.
Run Code Online (Sandbox Code Playgroud)
您还可以做更多的事情。
生成标准ISO 8601格式的字符串。该P标志的开始。该W指示数周。
PW7
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat。
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
从哪里获得 java.time 类?
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter,和更多。
使用日期算术java.util.Calendar:
public static int getWeeksBetween (Date a, Date b) {
if (b.before(a)) {
return -getWeeksBetween(b, a);
}
a = resetTime(a);
b = resetTime(b);
Calendar cal = new GregorianCalendar();
cal.setTime(a);
int weeks = 0;
while (cal.getTime().before(b)) {
// add another week
cal.add(Calendar.WEEK_OF_YEAR, 1);
weeks++;
}
return weeks;
}
public static Date resetTime (Date d) {
Calendar cal = new GregorianCalendar();
cal.setTime(d);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Run Code Online (Sandbox Code Playgroud)
如果您的要求是开始日期是 2020 年 4 月 3 日,结束日期是 2020 年 4 月 7 日。两个日期相差 4 天。现在,两个日期之间的周数为 1,您可以使用下面的代码片段。
ChronoUnit.WEEKS.between(LocalDate startDate, LocalDate endDate);
Run Code Online (Sandbox Code Playgroud)
但是,如果您的要求是 2020 年 4 月 3 日在一周内,2020 年 4 月 7 日在另一周内,因此您希望两个日期之间的周数为 2,则可以使用以下代码片段。
LocalDate actualStartDate=...
LocalDate actualEndDate=...
LocalDate startDate = actualStartDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY))
LocalDate endDate = actualEndDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SATURDAY))
long daysBetweenTwoDates = ChronoUnit.DAYS.between(startDate, endDate);
int numberOfWeeks = (int)Math.ceil(daysBetweenTwoDates/7.0);
Run Code Online (Sandbox Code Playgroud)
在java 1.8中测试
| 归档时间: |
|
| 查看次数: |
40691 次 |
| 最近记录: |