【问题标题】:How to make start time and end time 12 am to 12 am?如何将开始时间和结束时间设置为上午 12 点到中午 12 点?
【发布时间】:2018-11-08 13:37:10
【问题描述】:

我希望我的计步器显示从上午 12 点到凌晨 12 点的步数,但我找不到可行的方法。我正在使用 Google 的健身 API

代码如下:

        Calendar cal = Calendar.getInstance();
        Date today = new Date();
        cal.setTime(today);
        long endTime = cal.getTimeInMillis();
        cal.add(Calendar.MONTH, -1);
        long startTime = cal.getTimeInMillis();

        java.text.DateFormat dateFormat = DateFormat.getDateInstance();
        Log.e("History", "Range Start: " + dateFormat.format(startTime));
        Log.e("History", "Range End: " + dateFormat.format(endTime));

//Check how many steps were walked and recorded in the last 7 days
        final DataReadRequest readRequest = new DataReadRequest.Builder()
                .aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
                .bucketByTime(1, TimeUnit.DAYS)
                .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
                .build();

        final DataReadResult dataReadResult = Fitness.HistoryApi.readData(mGoogleApiClient, readRequest).await(1,TimeUnit.MINUTES);

【问题讨论】:

  • This 应该会有所帮助。
  • 12 点到 12 点之间的 24 小时?那为什么要减去一个月呢?为什么评论说“过去 7 天”?
  • @M.Prokhorov 是的,下面的解决方案对我有用。之前我正在检索上周的数据,但我改变了主意。
  • 仅供参考,非常麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle
  • 仅供参考,日子并不总是从凌晨 12 点到 12 点。

标签: java android calendar


【解决方案1】:

java.time

您正在使用可怕的旧日期时间类,这些类在几年前被 JSR 310 中定义的 java.time 类所取代。

LocalDate

首先,获取感兴趣的日期。如果要“今天”,则必须指定时区。

LocalDate 类表示仅日期值,没有时间,也没有 time zoneoffset-from-UTC

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。

如果没有指定时区,JVM 会隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将您的 desired/expected time zone 明确指定为参数。

continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 2-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

如果你想使用 JVM 当前的默认时区,请求它并作为参数传递。如果省略,则隐式应用 JVM 的当前默认值。最好是明确的,因为默认值可能会在任何时候在运行时被 JVM 中任何应用程序的任何线程中的任何代码更改。

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

一天的第一刻

12 点到 12 点

一天并不总是从凌晨 12 点到 12 点!

永远不要假设一天的开始或结束。一天并不总是 24 小时,它可以是 23、23.5、25 或定义时区的政客们所设想的任何其他小时数。在某些日期的某些区域中,一天可能不是从 00:00 开始,它可能在其他时间开始,例如 01:00。让 java.time 确定一天的开始和结束时间。

半开

通常,定义时间跨度的最佳方法是半开放方法。在这种方法中,开头是inclusive,而结尾是exclusive。这避免了试图确定一天中确切的瞬间结束的挑战。一天从一个日期的第一刻开始,一直持续到但不包括下一个日期的第一刻。

ZonedDateTime zdtStart = ld.atStartOfDay( z ) ;  // First moment of the day as seen in the wall-clock time used by the people of a particular region as defined arbitrarily by their politicians (a time zone).
ZonedDateTime zdtStop = ld.plusDays( 1 ).atStartOfDay( 1 ) ;  // First moment of the day of the *following* date.

纪元参考日期和粒度

DataReadRequest.Builder::setTimeRange 的 Google API 计算了一些粒度,因为一些 epoch reference date。不幸的是,既没有指定粒度的限制,也没有指定纪元参考——并且有many epoch references在使用中。

我将猜测秒是最精细的粒度,并猜测 1970-01-01T00:00Z 是纪元参考。 java.time 类和可怕的旧 java.util.Date 类使用这个时期。

long secondsSinceEpoch_Start = zdtStart.toEpochSecond() ;
long secondsSinceEpoch_Stop = zdtStop.toEpochSecond() ;

调用 API。

            …
            .setTimeRange( 
                secondsSinceEpoch_Start , 
                secondsSinceEpoch_Stop , 
                TimeUnit.SECONDS
            )
            …

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

【讨论】:

    【解决方案2】:
    you can try like this
    
                Date date1 = new Date();
                SimpleDateFormat  formatter1 = new SimpleDateFormat("MMddyyyy"); 
                String format = formatter1.format(date1);
                SimpleDateFormat  formatter = new SimpleDateFormat("MMddyyyy hh:mm:ss"); 
                Calendar cal = Calendar.getInstance();
                Date today = formatter.parse(format+" 00:00:00");
                cal.setTime(today);
                long start = cal.getTimeInMillis();
                System.out.println("start time:"+start);
                Date date=formatter.parse(format+" 23:59:59");
                cal.setTime(date);
                long end = cal.getTimeInMillis();
                System.out.println("end time: "+end);
    
                Date tem= new Date();
    
                cal.setTime(tem);
    
                long present = cal.getTimeInMillis();
    
                System.out.println(present);
    

    【讨论】:

    • 不正确在三个方面。 (a) 使用此代码,将永远不会报告当天最后一秒发生的数据。 (b) 一天并不总是 24 小时。 (c) 一天并不总是从 00:00 开始。
    【解决方案3】:

    如果你需要一天的开始,你应该这样设置:

    Calendar cal = new GregorianCalendar();
    cal.clear(Calendar.HOUR); cal.clear(Calendar.AM_PM);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    // after all this we'd have the start of day.
    // works good if extracted to separate method, which is the unfortunate truth of working with  old calendar classes
    
    // minus one milli because Fit API treats includes end of range
    long end = cal.getTimeInMillis() - 1;
    
    cal.add(Calendar.MONTH, -1);
    long start = cal.getTimeInMillis();
    

    我也可能建议为此导入和使用 Joda 库(首选 Android 特定版本)。 使用 Joda(和 java.time 包,一旦 Java 8 在 Fit 上可用,稍作更改),您可以编写如下等效代码:

    DateTime date = LocalDate.now().toDateTimeAtStartOfDay();
    
    long end = date.getMillis() - 1;
    
    long start = date.minusMonths(1).getMillis();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多