代码之家  ›  专栏  ›  技术社区  ›  maio290

一串格式、长时间和日期时间转换

  •  0
  • maio290  · 技术社区  · 4 年前

    如果问题是重复的,我道歉,我没有在谷歌上找到任何东西。

    对于我的问题:

    我有以下测试:

    public void testSecondsToMinutes() {
        long zero = 0;
        long thirty_seconds = 30;
        long one_minute = 60;
        long thirty_minutes_fiftynine_seonds = 1859;
        long two_hours_ten_miutes_fourty_seconds = 7840;
    
        String format1 = "00:00:00";
        String format2 = "00:00:30";
        String format3 = "00:01:00";
        String format4 = "00:30:59";
        String format5 = "02:10:40";
    
        assertEquals(format1,Entrypoint.secondsToMinutes(zero));
        assertEquals(format2,Entrypoint.secondsToMinutes(thirty_seconds));
        assertEquals(format3,Entrypoint.secondsToMinutes(one_minute));
        assertEquals(format4,Entrypoint.secondsToMinutes(thirty_minutes_fiftynine_seonds));
        assertEquals(format5,Entrypoint.secondsToMinutes(two_hours_ten_miutes_fourty_seconds)); 
    }
    

    以及以下功能:

    public static String secondsToMinutes(long seconds)
    {
        return String.format("%TH:%TM:%TS", seconds, seconds, seconds);
    }
    

    用于 Formatter 声明如下:

    The following conversion characters are used for formatting common date/time compositions.
    This conversion may be applied to long, Long, Calendar, and Date.
    [...]
    'R' '\u0052'    Time formatted for the 24-hour clock as "%tH:%tM"
    'T' '\u0054'    Time formatted for the 24-hour clock as "%tH:%tM:%tS".
    

    然而,我得到了以下比较失败:

    expected 00:00:00 but was 01:00:00
    

    我肯定错过了一些明显的东西。。。

    0 回复  |  直到 4 年前
        1
  •  3
  •   Holger    4 年前

    当你经过一个 long String.format ,它被解释为从纪元开始的毫秒,这是一个完全不同于从午夜开始的预期秒数的实体。

    通过直接编码您的意图,您的问题最容易解决:

    public static String secondsToTwentyFourHourString(long seconds) {
        return String.format("%1$TH:%1$TM:%1$TS", LocalTime.ofSecondOfDay(seconds));
    }
    

    通过这种方式,可以指定不依赖于时区的操作。

    DateTimeFormatter :

    public static String secondsToTwentyFourHourString(long seconds) {
        return LocalTime.ofSecondOfDay(seconds)
            .format(DateTimeFormatter.ofPattern("HH:mm:ss"));
    }
    
        2
  •  2
  •   maio290    4 年前

    所以,要回答这个问题:

    我真的试过本地人 strftime 在C中:

    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char*argv[])
    {
            time_t t = 0;
            struct tm * tmp = localtime(&t);
            char outstr[200];
            strftime(outstr,sizeof(outstr),"%T",tmp);
            printf(outstr);
            exit(EXIT_SUCCESS);
    }
    

    由于使用了 localtime() 而不是 gmtime() .由于时间戳不包含任何时区,现在对我来说很明显,时间确实被调整到了我的时区,这是 CET 1970年1月1日。

    这项工作的肮脏解决办法是:

    public static String secondsToTwentyFourHourString(long seconds)
    {
        TimeZone current = TimeZone.getDefault();
        TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
        seconds *= 1000;
        try
        {return String.format("%1$TH:%1$TM:%1$TS", seconds);}
        finally
        {TimeZone.setDefault(current);}
    }
    

    更好的解决方案是使用Java 8的时间类:

    public static String secondsToTwentyFourHourString(long seconds)
    {
        ZonedDateTime zdt = ZonedDateTime.ofInstant(Instant.ofEpochSecond(seconds), ZoneId.of("UTC"));
        return zdt.format(DateTimeFormatter.ofPattern("HH:mm:ss")); 
    }
    
        3
  •  1
  •   Nicolas Dupouy    4 年前

    字符串格式方法需要日历才能工作。你不能只给几秒钟。 实际上,如果你单独启动每个测试,它们都不是绿色的。

    我使用了给出的回答 here 要编写更经典的解决方案:

    public class Entrypoint {
        public static String secondsToMinutes(long seconds)
        {
            long absSeconds = Math.abs(seconds);
            String positive = String.format(
                    "%02d:%02d:%02d",
                    absSeconds / 3600,
                    (absSeconds % 3600) / 60,
                    absSeconds % 60);
            return seconds < 0 ? "-" + positive : positive;
        }
    }