Java - 如何获取与系统日期无关的当前日期?

17

我想知道当前的日期和时间。

代码

Calendar.getInstance();

表示程序运行的系统日期和时间,系统日期可能不正确。

那么是否有任何方法可以获得正确的当前日期和时间,而不受程序所在系统的日期和时间的影响?


2
日期是一个相对的东西......除非你在指定时区,否则不存在所谓的“正确当前日期”。 - Eyal Schneider
好的,我怎样才能获取特定时区的正确日期和时间? - Amit
你需要从你当前系统的日期和时间开始 - 这样可以吗? - mmmmmm
3
为什么你不定期使用NTP来同步系统时钟?这是一个“已解决的问题”。即使设备经常离线,系统时钟也不应该漂移太多,以至于会“错误地显示年份!” - Donal Fellows
3
@Donal,你不知道Yatendra想做这件事的原因。也许他(她)编写了一款有试用期的软件,应该在某个日期后禁用。在这种情况下,您不能信任本地系统的日期和时间,因为用户可能会故意篡改它,使软件在试用期过期后仍然能够工作。 - Jesper
6个回答

41

在Java 1.1之前的版本中,使用Date类是标准的:

Date now = new Date();     // Gets the current date and time
int year = now.getYear();  // Returns the # of years since 1900

但是,在较新版本的Java中,Date类的许多内容已被弃用(特别是getYear方法)。现在更标准的做法是使用Calendar类:

Calendar now = Calendar.getInstance();   // Gets the current date and time
int year = now.get(Calendar.YEAR);       // The current year

10
哇,有29个赞,但它并没有回答问题,问题明确要求如何在系统时钟错误的情况下获取实际日期。 - Paul Tomblin
@Paul Tomblin 这个问题的原始标题是“Java - 如何获取当前年份?”,但与实际问题不符。已进行修改。 - ltlBeBoy
1
@ltlBeBoy,我猜期望回答者和点赞者读超过标题可能太多了。 - Paul Tomblin

7
我不完全理解你的问题,但我可以回答你的标题:
GregorianCalendar gc = new GregorianCalendar(System.getCurrentTimeMillis());
int year = gc.get(Calendar.YEAR);

4
如果你在互联网上,你可能能够询问一个已知并可信的时间来源。如果运行你的程序的人想要防止你的程序这样做(比如如果你给他们一个有时间限制的许可证,他们不想支付更多时间),他们可能会伪造或阻止该连接。
在我参与的一个项目中,我们在硬件中放置了一个安全、可信赖的时间源,它无法被篡改。它专为加密和许可证而设计,并且有一个Java库来访问它。很抱歉,我不记得设备的名字了。
所以答案可能是肯定的,也可能是否定的。

3

0
以下是一些代码,可从您选择的Web服务器中获取HTTP格式(通常为UTC时区)的日期。
当然,如果您无法控制物理硬件和操作系统,则无法保证您能够与要求的实际Web服务器进行通信...但无论如何。
package some.package;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;

public class Test {

  private static String getServerHttpDate(String serverUrl) throws IOException {
    URL url = new URL(serverUrl);
    URLConnection connection = url.openConnection();

    Map<String, List<String>> httpHeaders = connection.getHeaderFields();

    for (Map.Entry<String, List<String>> entry : httpHeaders.entrySet()) {
      String headerName = entry.getKey();
      if (headerName != null && headerName.equalsIgnoreCase("date")) {
        return entry.getValue().get(0);
      }
    }
    return null;
  }

  public static void main(String[] args) throws IOException {
    String serverUrl = args.length > 0 ? args[0] : "https://google.com";
    System.out.println(getServerHttpDate(serverUrl));
  }

}

0

编程级别的方法是从系统本身获取日期和时间。您无法修改它们以获取除系统指定日期之外的日期。

对于您的额外要求,如果您真的需要它,您需要在客户端机器和服务器之间进行同步。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接