java中获取当前时间的方法(java获取date的年月日)
前言
上一周在做一个产品的需求的时候有个动态计算时间段(如现在是13:00,则时间段为15:10-17:10、17:10-19:10、19:10-21:10;即最早的出发时间为当前时间+参数【2h10min】,最迟的时间段为开始时间在20点前结束时间在20点后的时间段),期间大量使用到了日期时间类库,本着熟悉日期时间类库才有了这篇文章,文章最后我会把我如何实现的这个需求的一个算法贴出来。
一、jdk8以前版本中的时间类库
1.1 原始时间类库存在的缺陷与不足
我们在使用java8之前的类库时,都会在处理日期-时间的时候总是不爽,这其中包括且不限于以下的槽点:
在java 1.0版本中,对时间、日期的操作完全依赖于 java.util.data 类,只能以毫秒的精度表示时间,无法表示日期。
- 在易用性方面有着很大的缺陷,年份的起始时间选择是1900年,月份是从0开始。
- tostring 方法返回值不直观,带有时区。
在java1.1 版本中,废弃了很多date 类中的很多方法,并且新增了 java.util.calendar。但是与date相同,calendar 类也有类似的问题和设计缺陷,导致在使用这些类写出的代码也很容易出错。
- 月份依然是从0开始计算。
- 常用的日期、时间操作需要同时使用date、canendar、simpledateformat,比较繁琐。
- 部分特性只存在于某一个类(解析和格式化日期或时间的dateformat方法只存在于date类中)。
- dateformat 不是线程安全的,如果两个线程尝试使用同一个formatter 解析日期,可能会得到无法预期的结果。
- date 和 canendar 都是可变的。
1.2 关于simpledateformat 线程不安全的原因
由于 parse 方法使用的贡献变量 calendar 不是线程安全的。在 format (subformat) 方法中进行了 calendar 的赋值,在 parse 进行了值得处理,因此在并发的情况下会造成 calendar 清理不及时,值被覆盖的情况。
/**
* the {@link calendar} instance used for calculating the date-time fields
* and the instant of time. this field is used for both formatting and
* parsing.
*
* <p>subclasses should initialize this field to a {@link calendar}
* appropriate for the {@link locale} associated with this
* <code>dateformat</code>.
* @serial
*/
protected calendar calendar;
@override
public stringbuffer format(date date, stringbuffer toappendto,
fieldposition pos){
pos.beginindex = pos.endindex = 0;
return format(date, toappendto, pos.getfielddelegate());
}
// called from format after creating a fielddelegate
private stringbuffer format(date date, stringbuffer toappendto,
fielddelegate delegate) {
// convert input date to time field list
calendar.settime(date);
// at this point the fields of calendar have been set. calendar
// will fill in default values for missing fields when the time
// is computed.
pos.index = start;
date parseddate;
try {
parseddate = calb.establish(calendar).gettime();
// if the year value is ambiguous,
// then the two-digit year == the default start year
if (ambiguousyear[0]) {
if (parseddate.before(defaultcenturystart)) {
parseddate = calb.addyear(100).establish(calendar).gettime();
}
}
}
}
1.3 如何解决上述线程不安全问题?
- 使用threadlocal 为每个线程都创建一个线程独享 simpledateformat 变量;
- 需要的时候创建局部变量;
- 使用 org.apacle.commons.lang3.time.dateformatutils
- 使用joda-time (后面介绍)
二、joda-time 日期时间类库
2.1 简介
joda-time 是joda提供的一个遵循apache2.0 开源协议的 jdk以外的优质日期和时间开发库。
joda除joda-time之外的项目有joda-money、joda-beans、joda-convert、joda-collect joda官网
2.1.1 为什么使用joda-time
- 使用方便:calendar 访问“正常的”日期困难,并且缺乏简单的防腐,joda-time 拥有简单的字段访问,比如获得年的 getyear() 和 获得星期 中的天 getdayofweek() 。
- 易于扩展:jdk支持通过使用子类实现多个日历系统,但是这是非常笨重的,并且在实现中很难选出另一个日历系统。joda-time 支持基于 chronology 类实现多个可插拔的日历系统。
- 功能全面:joda-time 提供了所有的日期和时间计算的必须功能,它提供了即装即用的特性。
- 最新的时区计算:时区的实现基于公共时区信息数据库,每年更新数次。新版本的joda-time 包括了这个数据库的所有更改,应尽早进行必要的更新,手动更新区域数据很容易。
- 日历支持:提供了8种日历系统。
- 互通性:内部使用毫秒进行标识,这与jdk或者其他公共的时间表示相一致。
- 性能良好:支持针对所有访问的域进行最小的计算。
- 良好的测试覆盖率:有全方位的测试人员保证库的质量、
- 具有完整文档:有一个完整的用户指南,该指南提供了一个概述,涵盖常见的使用场景。javadoc 非常详细,涵盖api的其余部分。
- 发展:自2002年以来积极发展,是一个成熟的可靠的代码库,一些相关的项目目前也是可用的。
- 开源:遵循apache 2.0开源协议发布。
2.1.2 joda-time 的关键优点
- localdate:只包含日期
- localtime:只包含时间
- instant:时间轴上的时间点
- datetime:时区中完整的日期和时间
- datetimezone:更好的时区
- duration和period:持续时间
- interval:两个时间点之间的时间
- 全面并且灵活的时间格式化与转换
正因为joda-time 与 java8 之前的时间类库相比,具备了如此多的优点,所以 joda-time 成为事实上的标准的java日期和时间库。
2.2 特性解读
2.2.1 joda-time和jdk的互操作性
互操作性是指:joda 类能够生成 java.util.date 的实例(以及calendar),这可以让我们保留现有对jdk的依赖,又能够使用joda处理复杂的日期/时间计算。
date to joda-time
date date = new date();
datetime datetime = new datetime(date);
canendar to joda-time
calendar calendar = calendar.getinstance();
datetime datetime = new datetime(calendar);
joda-time to date
date date = new date();
datetime datetime = new datetime(date);
date date2 = datetime.todate();
joda-time to calendar
calendar calendar = calendar.getinstance();
datetime = new datetime(calendar);
calendar calendar2 = datetime.tocalendar(locale.china);
2.2.2 joda的关键日期/时间概念理解
joda 使用了以下概念,使得它们可以应用到任何日期/时间库:
不可变性(immutability)
joda-time与java.lang.string类似,它们的实例均无法修改(因为任意对其值改变的操作都会生成新的对象),这也代表了它们是线程安全的。
瞬时性(instant)
如接口 org.joda.time.readableinstant 中所表示的那样,instant 表示的是一个精确的时间点,是从 epoch:1970-01-01t00:00:00z 开始计算的毫秒数,这也的设计也使得其子类都可以与jdk date 以及 calendar 类兼容。
/**
* defines an instant in the datetime continuum.
* this interface expresses the datetime as milliseconds from 1970-01-01t00:00:00z.
* <p>
* the implementation of this interface may be mutable or immutable.
* this interface only gives access to retrieve data, never to change it.
* <p>
* methods in your application should be defined using <code>readableinstant</code>
* as a parameter if the method only wants to read the instant without needing to know
* the specific datetime fields.
* <p>
* the {@code compareto} method is no longer defined in this class in version 2.0.
* instead, the definition is simply inherited from the {@code comparable} interface.
* this approach is necessary to preserve binary compatibility.
* the definition of the comparison is ascending order by millisecond instant.
* implementors are recommended to extend {@code abstractinstant} instead of this interface.
*
* @author stephen colebourne
* @since 1.0
*/
public interface readableinstant extends comparable<readableinstant> {
/**
* get the value as the number of milliseconds since
* the epoch, 1970-01-01t00:00:00z.
*
* @return the value as milliseconds
*/
long getmillis();
······
}
datetime 类继承图如下:
局部性(partial)
瞬时性表达的是与epoch相对的时间上的一个精确时刻,而一个局部时间指的是一个时间的一部分片段,其可以通过一些方法使得时间产生变动(本质上还是生成了新的类),这样可以把它当做重复周期中的一点,用到多个地方。
年表(chronology)
joda-time的设计核心就是年表(org.joda.time.chronology),从根本上将,年表是一种日历系统,是一种计算时间的特殊方式,并且在其中执行日历算法的框架。joda-time支持的8种年表如下所示:
- iso(默认) – org.joda.time.chrono.isochronology
- gj – org.joda.time.chrono.gjchronology
- gregorian – org.joda.time.chrono.gregorianchronology
- julian – org.joda.time.chrono.julianchronology
- coptic – org.joda.time.chrono.copticchronology
- buddhist – org.joda.time.chrono.buddhistchronology
- ethiopic – org.joda.time.chrono.ethiopicchronology
- islamic – org.joda.time.chrono.islamicchronology
以上的每一种年表都可以作为特定日历系统的计算引擎,是可插拔的实现。
时区(time zone)
具体定义详见百科解释,在实际编码过程中任何严格的时间计算都必须涉及时区(或者相对于gmt),joda-time中对应的核心类为org.joda.time.datetimezone,虽然日常的使用过程中,并未涉及到对时区的操作,但是datetimezone如何对datetime产生影响是比较值得注意的,此处不进行赘述。
2.3 具体使用方法
上面介绍我完了joda-time的一些概念,接下来具体使用我们来进行说明:
2.3.1 创建 joda-time 对象
瞬时性-readableinstant
// 1.使用系统时间
datetime datetime1 = new datetime();
// 2.使用jdk中的date
date jdkdate1 = new date();
datetime datetime2 = new datetime(jdkdate1);
// 3.使用毫秒数指定
date jdkdate2 = new date();
long millis = jdkdate.gettime();
datetime datetime3 = new datetime(millis);
// 4.使用calendar
calendar calendar = calendar.getinstance();
datetime datetime4 = new datetime(calendar);
// 5.使用多个字段指定一个瞬间时刻(局部时间片段)
// year month day hour(midnight is zero) minute second milliseconds
datetime datetime5 = new datetime(2000, 1, 1, 0, 0, 0, 0);
// 6.由一个datetime生成另一个datetime
datetime datetime6 = new datetime(datetime1);
// 7.有时间字符串生成datetime
string timestring = "2019-01-01t00:00:00-06:00";
datetime datetime7 = datetime.parse(timestring);
局部性-readablepartial
当程序中处理的日期、时间并不需要是完整时刻的时候,可以创建一个局部时间,比如只希望专注于年/月/日, 或者一天中的时间,或者是一周中的某天。joda-time中有表示这些时间的是org.joda.time.readablepartial接口,实现它的两个类localdate和localtime是分别用来表示年/月/日和一天中的某个时间的。
// 显示地提供所含的每个字段
localdate localdate = new localdate(2019, 1, 1);
// 6:30:06 pm
localtime localtime = new localtime(18, 30, 6, 0);
localdate是替代了早期joda-time版本中使用的org.joda.time.yearmonthday,localtime是替代早期版本的org.joda.time.timeofday。(均已被标注为过时状态)。
时间跨度
joda-time提供了三个类用于表示时间跨度(在某些业务需求中,它们可能会非常有用)。
- duration
这个类表示以毫秒为单位的绝对精度,提供标准数学转换的方法,同时把时间跨度转换为标准单位。
- period
这个类表示以年月日单位表示。
- interval
这个类表示一个特定的时间跨度,使用一个明确的时刻界定这段时间跨度的范围。interval 为半开 区间,所以由其封装的时间跨度包括这段时间的起始时刻,但是不包含结束时刻。
2.3.2 使用joda-time的方法处理时间
datetime today = new datetime();
// 获取777秒之前的时间
datetime datetime1 = today.minus(777 * 1000);
// 获取明天的时间
datetime tomorrow = today.plusdays(1);
// 获取当月第一天的日期
datetime datetime2 = today.withdayofmonth(1);
// 获取当前时间三个月后的月份的最后一天
datetime datetime3 = today.plusmonths(3).dayofmonth().withmaximumvalue();
下面列出部分datetime方法列表: plus/minus开头的方法(比如:plusday, minusmonths):用来返回在datetime实例上增加或减少一段时间后的实例
- plus(long duration) 增加指定毫秒数并返回
- plusyears(int years) 增加指定年份并返回
- plusmonths(int months) 增加指定月份并返回
- plusweeks(int weeks) 增加指定星期并返回
- plusdays(int days) 增加指定天数并返回
- plushours(int hours) 增加指定小时并返回
- plusminutes(int minutes) 增加指定分钟并返回
- plusseconds(int seconds) 增加指定秒数并返回
- plusmillis(int millis) 增加指定毫秒并返回
与之相反的是minus前缀的 plus是增加 minus是减少
with开头的方法:用来返回在datetime实例更新指定日期单位后的实例
- withcenturyofera(int centuryofera) 更新时间世纪单位并返回
- withyearofcentury(int yearofcentury)更新世纪年并返回
- withyear(int year) 更新时间年并返回
- withweekyear(int weekyear) 更新时间周数并返回
- withmonthofyear(int monthofyear)更新时间月份并返回
- withdayofyear(int dayofyear) 更新时间天数并返回
- withdayofmonth(int dayofmonth) 更新时间天数并返回
- withdayofweek(int dayofweek) 更新时间天数并返回
- withhourofday(int hour) 更新时间小时并返回
- withminuteofhour(int minute) 更新时间分钟并返回
- withsecondofminute(int second) 更新时间秒数并返回
- withmillisofsecond(int millis) 更新时间毫秒并返回
- withmillisofday(int millis) 更新时间毫秒并返回
- withtimeatstartofday() 获取当天最早时间
判断datetime对象大小状态的一些操作方法
- compareto(datetime d) 比较两时间大小 时间大于指定时间返回 1 时间小于指定时间返回-1 相等返回0
- equals(datetime d) 比较两时间是否相等
- isafter(long instant) 判断时间是否大于指定时间
- isafternow() 判断时间是否大于当前时间
- isbefore(long instant) 判断时间是否小于指定时间
- isbeforenow() 判断时间是否小于当前时间
- isequal(long instant) 判断时间是否等于指定时间
- isequalnow() 判断时间是否等于当前时间
2.3.3 以joda-time的方式格式化时间
// 传入的格式化模板只需与jdk simpledateformat兼容的格式字符串即可
public static string convert(date date,string dateformat){
return new datetime(date).tostring(dateformat);
}
// 将jdk中的date转化为utc时区的datetime
datetime datetime = new datetime(new date(), datetimezone.utc);
// 将string转换为datetime
public static date convertutc2date(string utcdate){
datetime datetime =datetime.parse(utcdate, datetimeformat.forpattern("yyyy-mm-dd't'hh:mm:ss.sssz"));
return datetime.todate();
}
更多使用方法请参考官方文档。
三、java 8中新的时间类库
3.1 简介
由于jdk之前版本的类库的缺陷和糟糕的使用体验,再加上已经成为事实标准joda-time的影响力,oracle决定在java api中提供高质量的日期和时间支持,这也就是整合了大部分joda-time特性的jdk 8新的时间类库。(joda-time的作者实际参与开发,并且实现了jsr310的全部内容,新的api位于java.time下。常用的类有以下几个:localdate、localtime、instant、duration和period。)
由于jdk 8 新的时间类库大量借鉴了joda-time的设计思想乃至命名,因此如果你是joda-time的使用者,那你可以无学习成本的使用新的api(当然,它们之间也存在些许差别需要注意到)。
3.2 使用方法
3.2.1 使用localdate 和localtime
首先是localdate,该类的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关的信息。
// 使用指定的日期创建localdate
localdate date = localdate.of(2019, 1, 1);
// 获取当前日期
localdate today = localdate.now();
// 获取今日的属性
int year = date.getyear();
month month = date.getmonth();
int day = date.getdayofmonth();
dayofweek dow = date.getdayofweek();
int len = date.lengthofmonth();
boolean leap = date.isleapyear();
// 通过chronofield的枚举值获取需要的属性字段
int year = date.get(chronofield.year);
接着是localtime,它表示了一天内的某个时刻。
localtime time = localtime.of(18, 18, 18);
int hour = time.gethour();
int minute = time.getminute();
int second = time.getsecond();
localdate和localtime都可以通过使用静态方法parse来解析字符串进行创建。
localdate date = localdate.parse("2019-01-01");
localtime time = localtime.parse("18:18:18");
也可以向parse方法传递一个datetimeformatter,该类的实例定义了如何格式化一个日期或者时间对象。它其实是老版java.util.dateformat的替代品。
3.2.2 localdatetime
// 直接创建localdatetime
localdatetime dt1 = localdatetime.of(2019, month.january, 1, 18, 18, 18);
// 合并日期和时间
localdate date = localdate.parse("2019-01-01");
localtime time = localtime.parse("18:18:18");
localdatetime dt2 = localdatetime.of(date, time);
localdatetime dt3 = date.attime(18, 18, 18);
localdatetime dt4 = date.attime(time);
localdatetime dt5 = time.atdate(date);
// 从localdatetime中提取localdate或者localtime
localdate date1 = dt1.tolocaldate();
localtime time1 = dt1.tolocaltime();
3.3.3 instant
instant类是为了方便计算机理解的而设计的,它表示一个持续时间段上某个点的单一大整型数,实际上它是以unix元年时间(传统的设定为utc时区1970年1月1日午夜时分)开始所经历的秒数进行计算(最小计算单位为纳秒)。
// 传递一个秒数已创建该类的实例
instant.ofepochsecond(3);
// 传递一个秒数+纳秒 2 秒之后再加上100万纳秒(1秒)
instant.ofepochsecond(2, 1_000_000_000);
3.3.4 duration与period
duration是用于比较两个localtime对象或者两个instant之间的时间差值。
duration d1 = duration.between(time1, time2);
duration d1 = duration.between(datetime1, datetime2);
duration d2 = duration.between(instant1, instant2);
period是用于对年月日的方式对多个时间进行比较。
period tendays = period.between(localdate.of(2019, 1, 1), lcaldate.of(2019, 2, 2));
当然,duration和period类都提供了很多非常方便的工厂类,直接创建对应的实例。
duration threeminutes = duration.ofminutes(3);
duration threeminutes = duration.of(3, chronounit.minutes);
period tendays = period.ofdays(10);
period threeweeks = period.ofweeks(3);
period twoyearssixmonthsoneday = period.of(2, 6, 1);
3.3.5 操作、解析和格式化日期
// 直接使用withattribute的方法修改
localdate date1 = localdate.of(2019, 1, 1);
localdate date2 = date1.withyear(2019);
localdate date3 = date2.withdayofmonth(1);
localdate date4 = date3.with(chronofield.month_of_year, 1);
所有声明了temporal接口的类localdate、localtime、localdatetime以及instant,它们都使用get和with方法,将对象值的读取和修改区分开,如果使用了不支持的字段访问字段,会抛出一个unsupportedtemporaltypeexception异常。类似的,plus方法和minus方法都声明于temporal接口。通过这些方法,对temporalunit对象加上或者减去一个数字,我们能非常方便地将temporal对象前溯或者回滚至某个时间段,通过chronounit枚举我们可以非常方便地实现temporalunit接口。
3.3.6 更多定制化的处理时间
向重载的with方法传递一个定制化的temporaladjuster对象,可以更加灵活地处理日期。时间和日期的api已经提供了大量预定义的temporaladjuster,可以通过temporaladjuster类的静态工厂方法访问它们。这些方法的名称非常直观,方法名就是问题描述。某些情况下,如果你需要定义自己的temporaladjuster,只需要声明temporaladjuster接口并且自己实现对应的方法即可。
localdate date1 = localdate.of(2014, 3, 18);
localdate date2 = date1.with(temporaladjuster.nextorsame(dayofweek.sunday));
localdate date3 = date2.with(temporaladjuster.lastdayofmonth());
3.3.7 解析日期-时间对象
日常工作中,格式化以及解析日期-时间对象是另一个非常重要的功能,而新的java.time.format包就是特别为我们达到这个目的而设计的。这其中,最重要的类是datetimeformatter。所有的datetimeformatter实例都能用于以一定的格式创建代表特定日期或时间的字符串。(与老的java.util.dateformat相比较,所有的datetimeformatter实例都是线程安全的)
// 使用不同的格式器生成字符串
localdate date = localdate.of(2019, 1, 1);
string s1 = date.format(datetimeformatter.basic_iso_date);
string s2 = date.format(datetimeformatter.iso_local_date);
// 生成localdate对象
localdate date1 = localdate.parse("20190101", datetimeformatter.basic_iso_date);
localdate date2 = localdate.parse("2019-01-01", datetimeformatter.iso_local_date);
// 使用特定的模式创建格式器
datetimeformatter formatter = datetimeformatter.ofpattern("dd/mm/yyyy");
localdate date1 = localdate.of(2019, 1, 1);
string formatteddate = date1.format(formatter);
localdate date2 = localdate.parse(formatteddate, formatter);
3.3.8 处理不同的时区和日历系统
在新的日期-时间类库中,为了最大程度上的减少在处理时区带来的繁琐和复杂而使用了新的java.time.zoneid类(与其他日期和时间类一样,zoneid类也是无法修改的) 来替代老版的java.util.timezone。时区是按照一定的规则将区域划分成标准时间相同的区间。在zonerules这个类中包含了40个这样的实例。可以简单地通过调用zoneid的getrules()得到指定时区的规则。每个特定的zoneid对象都由一个地区id标识,地区id都为“{区域}/{城市}”的格式。比如:
zoneid romezone = zoneid.of("asia/shanghai");
java 8中在原先的timezone中加入了新的方法tozoneid,其作用是将一个老的时区对象转换为zoneid:
zoneid zoneid = timezone.getdefault().tozoneid();
得到的zoneid对象后可以将它与localdate、localdatetime或者是instant对象整合起来,构造为一个zoneddatetime实例,它代表了相对于指定时区的时间点:
localdate date = localdate.of(2019, month.january, 1);
zoneddatetime zdt1 = date.atstartofday(romezone);
localdatetime datetime = localdatetime.of(2019, month.january, 18, 13, 45);
zoneddatetime zdt2 = datetime.atzone(romezone);
instant instant = instant.now();
zoneddatetime zdt3 = instant.atzone(romezone);
通过zoneid,还可以将localdatetime转换为instant:
localdatetime datetime = localdatetime.of(2019, month.january, 18, 13, 45);
instant instantfromdatetime = datetime.toinstant(romezone);
同样可以通过反向的方式得到localdatetime对象:
instant instant = instant.now();
localdatetime timefrominstant = localdatetime.ofinstant(instant, romezone);
与joda-time所不同的是,java8中的日期-时间类库提供了4种其他的日历系统,这些日历系统中的每一个都有一个对应的日志类,分别是thaibuddhistdate、minguodate 、japanesedate 以及hijrahdate 。所有这些类以及localdate 都实现了chronolocaldate接口,能够对公历的日期进行建模。利用localdate对象,你可以创建这些类的实例。同样的,利用它们提供的静态工厂方法,你可以创建任何一个temporal对象的实例。
localdate date = localdate.of(2019, month.january, 1);
japanesedate japanesedate = japanesedate.from(date);
参考资料
joda-time 简介 joda time项目和java8时间api
动态计算时间段
需求:如现在是13:00,则时间段为15:10-17:10、17:10-19:10、19:10-21:10;即最早的出发时间为当前时间+参数【2h10min】,最迟的时间段为开始时间在20点前结束时间在20点后的时间段),求解共有多少个时间段?
分析:
- 第一个时间段的开始时间:当前时间+参数【2h10min】,中间的时间段是2h;
- 通过理解这句:最迟的时间段为开始时间在20点前结束时间在20点后的时间段,我们可以假设最大的时间变量为 max
- 假设当前时间为now,总共有n个时间段,可以推导出公式:now + (2h * n) + 10min <= max;
注意:计算过程都转换成毫秒
public class test {
// 毫秒
static final long slot = 130 * 60 * 1000;
private static list<timeselectitem> buildstartendtime(long now, long max) {
// now + (2h * n) + 10min <= max;
long n = (max - now - 60 * 1000) / (120 * 60 * 1000);
system.out.println("max:" + max);
system.out.println("now:" + now);
system.out.println(" max - now:" + (max - now));
system.out.println("n:" + n);
list<timeselectitem> timeselectitems = new arraylist<>();
long starttimestamp = now + slot;
long endtimestamp = starttimestamp + 120 * 60 * 1000;
for (int i = 1; i <= n; i++) {
// 起始时间
// starttimestamp = starttimestamp + i * (120 * 60 * 1000);
// 结束时间
endtimestamp = starttimestamp + (120 * 60 * 1000);
system.out.println(starttimestamp);
system.out.println(endtimestamp);
timeselectitem item = new timeselectitem();
datetime dt = new datetime(starttimestamp);
int hour = dt.hourofday().get();
int millis = dt.getminuteofhour();
string starttag = hour + ":" + millis;
datetime dt1 = new datetime(endtimestamp);
int hour1 = dt1.hourofday().get();
long millis1 = dt1.getminuteofhour();
string entag = hour1 + ":" + millis1;
item.setdisplayname(starttag + " - " + entag);
item.setstarttimestamp(starttimestamp);
item.setendtimestamp(endtimestamp);
timeselectitems.add(item);
starttimestamp = endtimestamp;
}
return timeselectitems;
}
public static void main(string[] args) {
long start = datetime.now().getmillis();
calendar c = calendar.getinstance();
c.settime(new date());
c.set(calendar.hour_of_day, 20);
c.set(calendar.minute, 0);
c.set(calendar.second, 0);
datetime dt = new datetime();
dt.withhourofday(20);
long end = c.gettimeinmillis();
// list<timeselectitem> list = buildstartendtime(1614747600000l, 1614772800000l);
list<timeselectitem> list = buildstartendtime(1614834000000l, end);
for (timeselectitem item : list ) {
system.out.println(item);
}
}
}