如何检查时间戳(纪元时间)是今天还是昨天的[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 进行比较?

如何创建具有毫秒粒度的 Python 时间戳?

Postgres 选择从昨天开始存储为纪元的记录

如何在 python 中将普通时间戳转换为纪元时间戳

如何在 kotlin 中将纪元时间戳转换为 unix 十六进制时间戳?

比较特定时间间隔的不同格式的纪元日期