Java的日期类都是怎么用的

cnblogs 2024-09-30 15:39:01 阅读 96

Java中的Date

为什么用类表示日期,而不是像其他语言中那样用一个内置(built-in)类型来表示?例如,Visual Basic 中有一个内置的 date 类型,程序员可以采用#12/31/1999格式指定日期。看起来这似乎很方便,程序员只需要使用内置的 date 类型而不用考虑类。但实际上,VisualBasic 这样设计合适吗?在有些地区,日期表示为月日/年,而另外一些地区则表示为日1月/年。语言设计者是否能够预见这些问题呢?如果没有处理好这类问题,语言就有可能陷入混乱,对此感到不满的程序员也会丧失使用这种语言的热情。如果使用类,这些设计任务就交给了类库的设计者。如果类设计得不完善,那么其他程序员可以很容易地编写自己的类,改进或替代(replace)这些系统类(作为印证:Java的日期类库开始时有些混乱,现在已经重新设计了两次)。

<code>System.out.println(new Date());这个表达式会构造一个新对象啊你个,这个对象初始化为当前的日期和时间。

image-20240926194346958

或者可以对刚构造的对象应用一个方法。Date类中有一个<code>toString的方法。这个方法将生成日期的一个字符串描述。

image-20240926194605240

在这两个例子中,构造的对象只使用了一次。通常,可能希望保留所构造的现象从而能继续使用,为此我们把对象存放在一个变量里<code>Date rightnow = new Date(),rightnow引用了新构造的对象

image-20240926201214554

对象和对象变量之间存在着一个重要的区别

<code>Date startTime定义了一个对象变量startTime,它可以引用Date类型的对象。但是,一定要认识到它不是一个对象,而且实际上它没有引用任何对象。所以无法调用startTime.toString()方法。所以必须首先初始化startTime变量,可以写成startTime = rightnow或者startTime = new Date(),这两种写法都引用了同一个对象

image-20240926202640117

要认识到重要的一点:对象变量并不实际包含一个对象,它只是引用一个对象。在Java中,任何对象变量的值都是一个引用,指向存储在另外一个地方的某个对象。new 操作符的返回值也是一个引用。下面的语句:

Date startTime =new Date();有两个部分。表达式new Date()构造了一个Date类型的对象,它的值是新创建对象的一个引用。再将这个引用存储在 startTime 变量中。

可以显式地将对象变量设置为null,指示这个对象变量目前没有引用任何对象。

image-20240926203001884

Java的对象变量虽然引用了对象,但是C++中没有null作用,而且引用不能赋值。应当把对象变量看作是类似于C++的对象指针,例如:

Date rightNow; // Java

实际上等同于

Date* rightNow; //C++

一旦建立了这种关联,一切就清楚了。当然,只有使用了new调用后Date * 指针才会初始化。就这一点而言,C++与 Java的语法儿乎是一样的。

Date* rightNow= new Date();//C++

如果把一个变量复制到另一个变量,两个变量就指向同一个日期,即它们是同一个对象的指针。Java中的null引用对应于C+中的NULL指针。

所有的Java对象都存储在堆中。当一个对象包含另一个对象变量时,它只是包含另一个堆对象的指针。

在C++中,指针十分令人头疼,因为它们很容易出错。稍不小心就会创建一个错误的指针,或者使内存管理出问题。在Java语言中,这些问题都不复存在。如果使用一个没有初始化的指针,那么运行时系统将会产生一个行时错误,而不是生成随机的结果。另外,你不必担心内存管理问题,垃圾回收器会处理相关的事宜。

C++确实做了很大的努力,它通过支持复制构造器和赋值送算符来实现对象的自动复制。例如,一个链表(linked list)的副本是一个新链表,其内客与原始链表相同但是有一组独立的链接。这样一来就可以适当地设计类,使它们与内置类型有相同的复制行为。在Java中,必须使用cone方法获得一个对象的完整副本。

LocalDate类

Java的时间是用距离一个固定时间点的毫秒数表示的,这个时间就是所谓

的纪元。它是UTC时间1970年1月1日00:00:00。UTC就是Coordinated Universal Time国际协调时间。

类库设计者决定将保存时间与给时间点命名分开。所以,标准Java类库分别包含了两个类:一个是用来表示时间点的 Date 类;另一个是用大家熟悉的日历表示法表示日期的 LocalDate类。Java8引人了另外一些类来处理日期和时间的不同方面--有关内容参见卷Ⅱ第6章。

将时间度量与日历分开是一种很好的面向对象设计。通常,最好使用不同的类表示不同的概念。

不要使用构造器来构造LocalDate类的对象。实际上,应当使用静态工厂方法(factorymethod),它会代表你调用构造器。下面的表达式:

<code>LocalDate.now()会构造一个新对象,表示构造这个对象时的日期。

可以提供年、月和日来构造对应一个特定日期的对象:

LocalDate.of(1999,12,31)

当然,通常我们都希望将构造的对象保存在一个对象变量中:

LocalDate newYearsEve = LocalDate.of(1999, 12,31);

一旦有了一个 LocalDate对象,可以用方法getYear、getMonthValue和getDay0fMonth 得到年月和日:

image-20240926204551314

如果在向未来定一个时刻,比如增加1000天来计算是哪一天,我们可以使用plusday方法

image-20240926204801966

Java库的一个比较早的版本曾经有过另一个处理日历的类,名为<code>GregorianCalendar

GregorianCalendar someday = new GregorianCalendar(2000, 1, 27);

someday.add(Calendar.DAY_OF_MONTH, 1000);

int year = someday.get(Calendar.YEAR);

int month = someday.get(Calendar.MONTH);

int day = someday.get(Calendar.DAY_OF_MONTH);

image-20240926205600364

Eg:打印当月日历

<code>import java.time.DayOfWeek;

import java.time.LocalDate;

public class Main {

public static void main(String[] args) {

LocalDate date = LocalDate.now(); //首先构造一个对象,并用当前日期初始化

//获取当前月日

int month = date.getMonthValue();

int today = date.getDayOfMonth();

date = date.minusDays(today - 1);// 讲日期设置为当月第一天

DayOfWeek weekday = date.getDayOfWeek();//并得到这一天是星期几

int value = weekday.getValue();// 1=Monday,...,7= Sunday

System.out.println("Mon Tue Wed Thu Fri Sat Sun");

for (int i = 1; i < value; i++)

System.out.print(" ");

while (date.getMonthValue() == month) {

System.out.printf("%3d", date.getDayOfMonth());

if (date.getDayOfMonth() == today) {

System.out.print("*");

} else {

System.out.print(" ");

}

date = date.plusDays(1);

if (date.getDayOfWeek().getValue() == 1)

System.out.println();

}

if (date.getDayOfWeek().getValue() != 1)

System.out.println();

}

}

image-20240929172508929



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。