如何检查时间戳(纪元时间)是今天还是昨天的[android]
Posted
技术标签:
【中文标题】如何检查时间戳(纪元时间)是今天还是昨天的[android]【英文标题】:How to check if time stamp (epoch time) is of today's or yesterday's [android] 【发布时间】:2012-03-12 18:53:48 【问题描述】:我想将时间戳(纪元时间)转换为人类可读的字符串。
为此,我使用calendar.setTimeInMillis(timeSinceEpoch)
函数创建日历对象并以人类可读格式获取日期时间字符串。
我很困惑,我怎样才能知道时间戳(纪元时间)是今天还是昨天,或者它与系统的当前日期和时间在同一周?
是否有任何 API 可以在 android 中实现这一点?
谢谢。
【问题讨论】:
java epoch 时间为January 1, 1970
我的问题是,我可以根据当前系统时间和日期测试我以毫秒为单位的纪元时间,或者这个时间戳是否在当前周。希望这能解释清楚!
@PP... 那么您在下面已经有了答案..
【参考方案1】:
你可以使用方法:
public static long diff(long time, int field)
long fieldTime = getFieldInMillis(field);
Calendar cal = Calendar.getInstance();
long now = cal.getTimeInMillis();
return (time/fieldTime - now / fieldTime);
private static final long getFieldInMillis(int field)
// TODO cache values
final Calendar cal = Calendar.getInstance();
long now = cal.getTimeInMillis();
cal.add(field, 1);
long after = cal.getTimeInMillis();
return after - now;
并以这种方式使用它们:
diff(time, Calendar.DAY_OF_YEAR); // 0 - today, 1 - tomorrow, -1 - yesterday
diff(time, Calendar.WEEK_OF_YEAR); // 0 - this week, -1 - last week etc.
【讨论】:
对于尽力而为的解决方案,这很好。如果您需要准确的答案(小时或秒),请注意时间戳包括夏令时切换小时和闰秒,因此 getFieldInMillis 在这些情况下不会返回完全相同的值,结果可能会有点偏差。 (例如,在夏令时的前一天,它会将 23 或 25 天报告为 24 天,因为“下一个”天有 23 或 25 小时。要获得准确的答案,请通过调用 cal.add 来验证它们,结果是“尽力而为” " 评估并验证结果是否足够准确,如果没有更正。 注意前面的评论。【参考方案2】:其实很简单:
Calendar c=Calendar.getInstance();
c.getTimeInMillis();
String cur_day=String.format("%te %B %tY",c,c,c); // This will give date like 22 February 2012
c.setTimeInMillis(time);//set your saved timestamp
String that_day=String.format("%te %B %tY",c,c,c); //this will convert timestamp into format like 22 February 2012
//you can compare days,months,year,hours,minutes,seconds and milliseconds using above method.you can find various formats in below link
更多格式请参考http://download.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html
【讨论】:
实际上我的问题是,我可以测试从纪元时间开始的毫秒数是今天,昨天还是根据当前系统时间在同一周。 你必须自己实现。这种自动比较不可用。 所以它会像,为了比较它是否是今天,那么我必须获取当前系统时间并检查年、月和日期,然后我会知道时间戳是今天还是不是。 @PP.: yes..absolutely.you just need to be sure you compare it correcly and don't miss any related parameter.For.ex:检查时间不应该忽略上午/下午的差异。 【参考方案3】:您可以尝试使用它来检测今天的日期:
public static boolean isDateToday(long milliSeconds)
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(milliSeconds);
Date getDate = calendar.getTime();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date startDate = calendar.getTime();
return getDate.compareTo(startDate) > 0;
【讨论】:
更简单的方法:DateUtils.isToday()【参考方案4】:我认为这是确定两个时间戳是否在同一天的最有效方法。加上它与语言无关:
int secondsInADay = 60*60*24;
int daysSinceEpoch1 = timestamp1/secondsInADay;
int daysSinceEpoch2 = timestamp2/secondsInADay;
if( daysSinceEpoch1 == daysSinceEpoch2 )
;//sameday
else if( daysSinceEpoch1 - daysSinceEpoch2 == 1 )
;//timestamp2 is a day before timetamp1
else if( ......
如果要与今天比较,请将 timestamp1 设置为当前时间
【讨论】:
我需要的唯一更正是转换为 int,因为时间戳很长。否则,很好的答案。谢谢! 除了 secondsInADay 不起作用,因为不是每一天都有这个确切的时间量,因此您的方法会在一天中的某个时间导致错误的结果。【参考方案5】:java.time
旧的日期时间 API(java.util
日期时间类型及其格式类型,SimpleDateFormat
等)已过时且容易出错。建议完全停止使用,改用java.time
,modern date-time API*。
使用现代 API java.time
的解决方案:
现代日期时间 API 具有丰富的直观概念,例如它为我们提供了 Instant
类,它代表时间线上的一个瞬时点。有一个名为 ZonedDateTime
的类,它表示 ISO-8601 日历系统中带有时区的日期时间。为了切换到不同的时间单位(例如天、小时、分钟、周、月等),API 提供了称为介词和其他英语口语结构的方法。从 Trail: Date Time 了解有关现代日期时间 API 的更多信息。
今天、昨天、同一周等概念受时区限制,例如今天在伦敦的某个时刻可能是明天在新加坡的时刻。此外,start of the week 是 Locale
敏感的,例如对于Locale.France
,它从星期一开始,而对于Locale.US
,它从星期日开始。
演示:
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.stream.Stream;
public class Main
public static void main(String[] args)
// Test
Stream.of(
1621533017083L,
1621446617083L,
1621619417083L,
1621189684296L,
1621209600000L,
1621814400000L
).forEach(millis ->
System.out.println(millis);
System.out.println(Instant.ofEpochMilli(millis));
System.out.println("Today: " + isToday(millis, "Europe/London"));
System.out.println("Yesterday: " + isYesterday(millis, "Europe/London"));
System.out.println("In the current week: " + isInTheSameWeek(millis, "Europe/London"));
System.out.println();
);
static boolean isToday(long epochMillis, String timezone)
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
long millisStartOfDayToday = zdtStartOfDayToday.toInstant().toEpochMilli();
// The start of the next day at this timezone
ZonedDateTime zdtStartOfDayNextDay = LocalDate.now().plusDays(1).atStartOfDay(zoneId);
long millisStartOfDayNextDay = zdtStartOfDayNextDay.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfDayToday && epochMillis < millisStartOfDayNextDay);
static boolean isYesterday(long epochMillis, String timezone)
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
long millisStartOfDayToday = zdtStartOfDayToday.toInstant().toEpochMilli();
// The start of the day yesterday at this timezone
ZonedDateTime zdtStartOfDayYesterday = LocalDate.now().minusDays(1).atStartOfDay(zoneId);
long millisStartOfDayYesterday = zdtStartOfDayYesterday.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfDayYesterday && epochMillis < millisStartOfDayToday);
static boolean isInTheSameWeek(long epochMillis, String timezone)
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
// The start of the week at this timezone
ZonedDateTime zdtStartOfTheWeek = zdtStartOfDayToday.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
long millisStartOfTheWeek = zdtStartOfTheWeek.toInstant().toEpochMilli();
// The start of the next week at this timezone
ZonedDateTime zdtStartOfTheNextWeek = zdtStartOfDayToday.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
long millisStartOfTheNextWeek = zdtStartOfTheNextWeek.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfTheWeek && epochMillis < millisStartOfTheNextWeek);
输出:
1621533017083
2021-05-20T17:50:17.083Z
Today: true
Yesterday: false
In the current week: true
1621446617083
2021-05-19T17:50:17.083Z
Today: false
Yesterday: true
In the current week: true
1621619417083
2021-05-21T17:50:17.083Z
Today: false
Yesterday: false
In the current week: true
1621189684296
2021-05-16T18:28:04.296Z
Today: false
Yesterday: false
In the current week: false
1621209600000
2021-05-17T00:00:00Z
Today: false
Yesterday: false
In the current week: true
1621814400000
2021-05-24T00:00:00Z
Today: false
Yesterday: false
In the current week: false
ONLINE DEMO
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。
【讨论】:
【参考方案6】:时间应该以毫秒为单位
DateUtils.isToday(time)
【讨论】:
以上是关于如何检查时间戳(纪元时间)是今天还是昨天的[android]的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Unix 纪元时间戳与 SQL 中的 DATE 进行比较?