【问题标题】:How to convert currentTimeMillis to a date in Java?如何将 currentTimeMillis 转换为 Java 中的日期?
【发布时间】:2012-01-04 10:48:12
【问题描述】:

我在服务器中生成的某些日志文件中有毫秒,我也知道生成日志文件的语言环境,我的问题是将毫秒转换为指定格式的日期。 该日志的处理发生在位于不同时区的服务器上。虽然转换为“SimpleDateFormat”程序正在获取机器的日期,因为这样的格式化日期不代表服务器的正确时间。有什么方法可以优雅地处理这个吗?

long yourmilliseconds = 1322018752992l;
        //1322018752992-Nov 22, 2011 9:25:52 PM 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS",Locale.US);

GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
calendar.setTimeInMillis(yourmilliseconds);

System.out.println("GregorianCalendar -"+sdf.format(calendar.getTime()));

DateTime jodaTime = new DateTime(yourmilliseconds, 
                    DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");

System.out.println("jodaTime "+parser1.print(jodaTime));

输出:

Gregorian Calendar -2011-11-23 08:55:52,992
jodaTime 2011-11-22 21:25:52,992

【问题讨论】:

  • 不要将区域设置与时区混淆。完全分开。语言环境决定了月份和日期名称的人类语言,以及文化规范,例如月份、日期等部分的顺序。时区与 UTC 以及处理异常的规则(例如夏令时)不同。
  • 问题是毫秒数不是从 1970-01-01T00:00:00Z 开始计算,而是从其他时刻开始计算吗?
  • 仅供参考,糟糕的旧日期时间类(GregorianCalendarSimpleDateFormat 等)和出色的 Joda-Time 库现在都被现代 java.time 类。

标签: java date


【解决方案1】:

您可以使用java.util.Date 类,然后使用SimpleDateFormat 格式化Date

Date date=new Date(millis);

我们可以使用java.time 包(教程)-Java SE 8 中引入的 DateTime API。

var instance = java.time.Instant.ofEpochMilli(millis);
var localDateTime = java.time.LocalDateTime
                        .ofInstant(instance, java.time.ZoneId.of("Asia/Kolkata"));
var zonedDateTime = java.time.ZonedDateTime
                            .ofInstant(instance,java.time.ZoneId.of("Asia/Kolkata"));

// Format the date

var formatter = java.time.format.DateTimeFormatter.ofPattern("u-M-d hh:mm:ss a O");
var string = zonedDateTime.format(formatter);

【讨论】:

  • 不。并非java.util.Date 的所有方法都已折旧。 (在 JDK8 的 java.time 中有改进的日期和时间 API)
  • @RafaelZeffa ,'''Date(long date)''' 构造函数未被弃用
  • 提供 Date 对象是为了向后兼容。最好按照上面的建议使用日历。
  • 仅供参考,非常麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle
【解决方案2】:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);

【讨论】:

  • 我必须将 Calendar 设置为 final 才能使其正常工作。 final Calendar calendar = Calendar.getInstance();
  • 日历对象通常被认为非常大,因此应尽可能避免使用。假设 Date 对象具有您需要的功能,它会更好。 “日期日期=新日期(毫秒);”用户 AVD 在其他答案中提供的将是最佳路线:)
  • 不知何故,对于1515436200000l,我得到calendar.get(Calendar.MONTH))0
  • 仅供参考,非常麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat,现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle
  • @SajibAcharya 请注意 Calendar.MONTH 的实例从 0 开始;您需要添加一个才能获得我们所知道的“真实”月份。示例:0 = 一月,1 = 二月,2 = 三月,等等。
【解决方案3】:

tl;博士

Instant.ofEpochMilli( 1_322_018_752_992L )     // Parse count of milliseconds-since-start-of-1970-UTC into an `Instant`.
       .atZone( ZoneId.of( "Africa/Tunis" ) )  // Assign a time zone to the `Instant` to produce a `ZonedDateTime` object.

详情

其他答案使用过时或不正确的类。

避免使用旧的日期时间类,例如 java.util.Date/.Calendar。事实证明,它们设计不佳、令人困惑且麻烦。

java.time

java.time 框架内置于 Java 8 及更高版本中。大部分功能是backported to Java 6 & 7 和更多adapted to Android。由制作Joda-Time 的一些人制作。

InstantUTC 时间线上的一个时刻,分辨率为nanoseconds。它的epoch 是 1970 年 UTC 的第一刻。

假设您的输入数据是从 1970-01-01T00:00:00Z 开始的毫秒数(问题中不清楚),那么我们可以轻松实例化 Instant

Instant instant = Instant.ofEpochMilli( 1_322_018_752_992L );

instant.toString(): 2011-11-23T03:25:52.992Z

标准ISO 8601 格式化字符串中的ZZulu 的缩写,表示UTC

使用proper time zone name 应用时区,得到ZonedDateTime

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( zoneId );

看到这个code run live at IdeOne.com

Asia/Kolkata时区?

我猜你的印度时区会影响你的代码。我们在这里看到,调整到 Asia/Kolkata 时区会呈现与您报告的相同时间,08:55,这比我们的 UTC 值 03:25 提前五个半小时。

2011-11-23T08:55:52.992+05:30[亚洲/加尔各答]

默认区域

你可以应用JVM的current default time zone。请注意,默认值可以随时更改在运行时。 JVM 内任何应用程序的任何线程中的任何代码都可以更改当前默认值。如果重要,请询问用户他们想要/预期的时区。

ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

关于java.time

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

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

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

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

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

  • 将上面推荐的 Instant 转换为设备(例如智能手机)默认的本地时区是否容易?
  • @AJW 是的。致电ZoneId.systemDefault()。请参阅添加到我的答案末尾的新部分。
  • 好极了,我试试看。
【解决方案4】:

执行此操作的最简单方法是使用Joda DateTime class 并指定以毫秒为单位的时间戳和所需的 DateTimeZone。

我强烈建议避免使用内置的 Java Date 和 Calendar 类;他们太可怕了。

【讨论】:

  • GorgianCalender 不起作用...无论出于何种原因,它都占用了系统默认时区。乔达工作得很好。
  • 如果我们可以用 Gregorian 做一些不同的事情,请告诉我查看示例代码
  • 仅供参考,Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。见Tutorial by Oracle
【解决方案5】:

如果毫秒值是自格林威治标准时间 1970 年 1 月 1 日以来的毫秒数,这是 JVM 的标准,那么它与时区无关。如果要使用特定时区对其进行格式化,只需将其转换为 GregorianCalendar 对象并设置时区即可。之后有很多方法可以格式化它。

【讨论】:

  • 这是 GregorianCalendar 和 Joda 的示例代码,我使用 Joda 得到了正确的输出,但没有使用 Gregorian GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central")); calendar.setTimeInMillis(yourmilliseconds); DateTime jodaTime = new DateTime(yourmilliseconds,DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central"))); DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS");
  • 在日历对象中设置时区不起作用,但在日期格式化程序对象中设置它?
  • 什么是 DateTime 和 DateTimeFormatter??
【解决方案6】:

我的解决方案

public class CalendarUtils {

    public static String dateFormat = "dd-MM-yyyy hh:mm";
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

    public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(Long.parseLong(milliSeconds));
        return simpleDateFormat.format(calendar.getTime());
    }
}

【讨论】:

    【解决方案7】:

    最简单的方法:

    private String millisToDate(long millis){
    
        return DateFormat.getDateInstance(DateFormat.SHORT).format(millis);
        //You can use DateFormat.LONG instead of SHORT
    
    }
    

    【讨论】:

      【解决方案8】:

      我是这样做的:

      static String formatDate(long dateInMillis) {
          Date date = new Date(dateInMillis);
          return DateFormat.getDateInstance().format(date);
      }
      

      您还可以使用getDateInstance(int style) 和以下参数:

      DateFormat.SHORT

      DateFormat.MEDIUM

      DateFormat.LONG

      DateFormat.FULL

      DateFormat.DEFAULT

      【讨论】:

        【解决方案9】:

        SimpleDateFormat 类有一个名为 SetTimeZone(TimeZone) 的方法,该方法继承自 DateFormat 类。 http://docs.oracle.com/javase/6/docs/api/java/text/DateFormat.html

        【讨论】:

        • 仅供参考,随着 JSR 310 的采用,这些糟糕的类现在被现代的 java.time 类所取代。
        【解决方案10】:

        你可以试试java.time api;

                Instant date = Instant.ofEpochMilli(1549362600000l);
                LocalDateTime utc = LocalDateTime.ofInstant(date, ZoneOffset.UTC);
        

        【讨论】:

          【解决方案11】:

          以下是我将日期从毫秒转换为日期格式的解决方案。您必须使用Joda Library 才能运行此代码。

          import java.util.GregorianCalendar;
          import java.util.TimeZone;
          
          import org.joda.time.DateTime;
          import org.joda.time.DateTimeZone;
          import org.joda.time.format.DateTimeFormat;
          import org.joda.time.format.DateTimeFormatter;
          
          public class time {
          
              public static void main(String args[]){
          
                  String str = "1431601084000";
                  long geTime= Long.parseLong(str);
                  GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("US/Central"));
                  calendar.setTimeInMillis(geTime);
                  DateTime jodaTime = new DateTime(geTime, 
                         DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Central")));
                  DateTimeFormatter parser1 = DateTimeFormat.forPattern("yyyy-MM-dd");
                  System.out.println("Get Time : "+parser1.print(jodaTime));
          
             }
          }
          

          【讨论】:

            【解决方案12】:
            public static LocalDateTime timestampToLocalDateTime(Long timestamp) {
                return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), TimeZone.getDefault().toZoneId());
            }
            

            【讨论】:

            • 现有答案的重复? stackoverflow.com/a/54666195/5990117
            • 我建议你不要使用TimeZone。该类设计不佳且早已过时,在这里使用它涉及不必要的转换。只需LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault())
            【解决方案13】:
             public static String getFormatTimeWithTZ(Date currentTime) {
                SimpleDateFormat timeZoneDate = new SimpleDateFormat("EEE, dd-MM-yyyy  hh:mm a", Locale.getDefault());
                return timeZoneDate.format(currentTime);
            }
            

            输出是

            Mon,01-03-2021 07:37 PM
            

            public static String getFormatTimeWithTZ(Date currentTime) {
                SimpleDateFormat timeZoneDate = new SimpleDateFormat("EEE, dd-MM-yyyy  HH:mm ", Locale.getDefault());
                return timeZoneDate.format(currentTime);
            }
            

            输出是

            Mon,01-03-2021 19:37
            

            如果您不想要 Days Then Remove EEE,
            如果您不想要日期,则删除 dd-MM-yyyy
            如果您想要以小时、分钟、秒、毫秒为单位的时间,请使用 HH:mm:ss.SSS

            然后在你想要的地方调用这个方法

            getFormatTimeWithTZ(Mydate)
            

            在哪里

            Date Mydate = new Date(System.currentTimeMillis());
            

            【讨论】:

              猜你喜欢
              • 2012-05-09
              • 2017-12-25
              • 2012-08-12
              • 2021-06-07
              • 1970-01-01
              • 1970-01-01
              • 2015-02-06
              • 2021-11-10
              相关资源
              最近更新 更多