Click “like” to see, form a habit, the public account search [dime technology] pay attention to more original technical articles. This article has been included in GitHub org_Hejianhui /JavaStudy.
preface
Last week, there was a dynamic calculation period when making a product requirement (for example, now it is 13:00, then the time period is 15:10-17:10, 17:10-19:10, 19:10-21:10; Is the earliest departure time parameters for the current time + h10min [2], the latest time for the start time at the end of the 20 o ‘clock time period after 20 points), extensive use of the date/time during class libraries, in line with the familiar date time class library to this article, finally I will put my how to implement the requirements of an algorithm to stick out.
Time class library in JDK8 prior
1.1 Defects and deficiencies of the original time inventory
All of our pre-Java8 libraries have had trouble dealing with date-time, including but not limited to the following slots:
In Java version 1.0, the manipulation of time and date is entirely dependent on the java.util.Data class, which can only represent time in milliseconds, not dates.
- There is a big flaw in ease of use, with the year starting from 1900 and the month starting from 0.
- The toString method returns an unintuitive value with a time zone.
In Java1.1, many methods in many Date classes were deprecated and java.util.calendar was added. But like Date, the Calendar classes have similar problems and design flaws that make code written using them error-prone.
- The months are still going to start at 0.
- Common Date and time operations need to use Date, Canendar, and SimpleDateFormat at the same time, which is complicated.
- Part feature exists only in a certain class (parsing and formatting the DateFormat method of futures time exists only in the Date class).
- DateFormat is not thread-safe, and if two threads try to parse dates using the same Formatter, they may get unexpected results.
- Date and Canendar are mutable.
1.2 Reasons why SimpleDateFormat thread is unsafe
Since the contributed calendar variable used by the Parse method is not thread-safe. Calendar is assigned in the format (subFormat) method, which is worth processing in parse. Therefore, in the case of concurrency, calendar is not cleaned in time and values are overwritten.
/**
* 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(); }}}}Copy the code
1.3 How do I Solve the thread Insecurity problem?
- Create a thread-exclusive SimpleDateFormat variable for each thread using ThreadLocal;
- Create local variables as needed;
- Use org.apacle.com mons. Lang3. Time. DateFormatUtils
- Using joda-time (described below)
Joda-time date-time class library
2.1 introduction
Joda-time is a quality date and Time development library provided by Joda that follows the Apache2.0 open source protocol in addition to the JDK.
Joda: Joda-money: Joda-beans: Joda-convert: Joda-collect: Joda-collect: Joda-collect: Joda-money: Joda-beans: Joda-convert: Joda-collect: Joda-collect: Joda-money: Joda-beans: Joda-convert: Joda-collect: Joda-collect
2.1.1 Why is Joda-time used
- Ease of use: Calendar is difficult to access “normal” dates and lacks simple anticorrosions, while Joda-time has simple field access, such as getting the year’s
getYear()
And get the day of the weekgetDayOfWeek()
。 - Easy to extend: The JDK supports implementing multiple calendar systems by using subclasses, but this is cumbersome, and it is difficult to implement another calendar system first. Joda-time supports based on
Chronology
Class to implement multiple pluggable calendar systems. - Full-featured: Joda-time provides all the necessary functionality for date and Time calculations, and it provides out-of-the-box features.
- Up-to-date time zone calculations: Time zone implementations are based on a common time zone information database, updated several times a year. The new version of Joda-Time includes all changes to this database, and the necessary updates should be made as soon as possible, as it is easy to update the zone data manually.
- Calendar support: Provides 8 calendar systems.
- Interoperability: Internal identification using milliseconds is consistent with the JDK or other common time representations.
- Good performance: Supports minimal computation for all domains accessed.
- Good test coverage: a full range of testers to ensure the quality of the library,
- Complete documentation: There is a complete user guide, which provides an overview and covers common usage scenarios. Javadoc is very detailed and covers the rest of the API.
- Development: actively developed since 2002, is a mature and reliable codebase, some related projects are also currently available.
- Open Source: Released under the Apache 2.0 open source license.
2.1.2 Key advantages of joda-time
- LocalDate: contains only the date
- LocalTime: contains only the time
- Instant: a point in time on the timeline
- DateTime: The complete date and time in the time zone
- DateTimeZone: Better time zone
- Duration and Period: indicates the Duration of time
- Interval: indicates the time between two time points
- Comprehensive and flexible time formatting and conversion
Because joda-time has so many advantages over the pre-Java8 Time libraries, joda-time has become the de facto standard Java date and Time library.
2.2 Feature Interpretation
2.2.1 Joda-time and JDK interoperability
Interoperability is the ability of the Joda class to generate instances of java.util.date (and Calendar), which allows us to retain our existing JDK dependencies while using Joda to handle complex Date/time calculations.
Date To Joda-Time
Date date = new Date();
DateTime dateTime = new DateTime(date);
Copy the code
Canendar To Joda-Time
Calendar calendar = Calendar.getInstance();
DateTime dateTime = new DateTime(calendar);
Copy the code
Joda-Time To Date
Date date = new Date();
DateTime dateTime = new DateTime(date);
Date date2 = dateTime.toDate();
Copy the code
Joda-Time To Calendar
Calendar calendar = Calendar.getInstance();
dateTime = new DateTime(calendar);
Calendar calendar2 = dateTime.toCalendar(Locale.CHINA);
Copy the code
2.2.2 Understanding of key date/time concepts of Joda
Joda uses the following concepts to make them applicable to any date/time library:
Immutability
Joda-time is similar to java.lang.String in that their instances cannot be modified (because any operation that changes their value generates a new object), which also means that they are thread-safe.
Instant
Such as interface org. Joda. Time. In the ReadableInstant suggests, Instant represents a precise point in time, from the epoch: 1970-01-0t00:00:00 Z The number of milliseconds to start counting, which is also designed so that subclasses are compatible with JDK Date and Calendar classes.
/**
* 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 {@codeCompareTo} method is no longer defined in this class in version 2.0. * Instead, the definition is simply inherited from the {@codeComparable} 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
* @since1.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(a); ......}Copy the code
The DateTime class inheritance diagram looks like this:
Partial
Temporality represents an exact moment in time relative to the epoch, while a local time refers to a fragment of time that can be changed (essentially generating new classes) in some way, so that it can be used in multiple places as a point in a repeating cycle.
Chronology
The core of the design of Joda-time is the Chronology (org.joda.time.chronology). Fundamentally, the Chronology is a calendar system, a special way to calculate Time, and a framework to execute the calendar algorithm in it. The chronology of the eight types supported by joda-time is as follows:
- ISO (the default) – 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
Each of the above chronologies can be used as a computing engine for a particular calendar system and is pluggable implementation.
Time Zone
Specific definition see an explanation, in the actual encoding any strict Time calculations must be involved in the process of Time zone (or relative to GMT), Joda – Time of the corresponding core classes for org. Joda. Time. DateTimeZone, although everyday in use process, pair is involved in operation, But how the DateTimeZone affects DateTime is worth noting and won’t be covered here.
2.3 Specific usage method
Joda-time: Joda-time: joda-time: Joda-time: Joda-time: Joda-time
2.3.1 Creating a Joda-time Object
Momentariness – ReadableInstant
// 1. Use system time
DateTime dateTime1 = new DateTime();
// 2. Use date in JDK
Date jdkDate1 = new Date();
DateTime dateTime2 = new DateTime(jdkDate1);
// 3. Specify milliseconds
Date jdkDate2 = new Date();
long millis = jdkDate.getTime();
DateTime dateTime3 = new DateTime(millis);
// 4. Use Calendar
Calendar calendar = Calendar.getInstance();
DateTime dateTime4 = new DateTime(calendar);
// 5. Specify a moment (partial time segment) with multiple fields
// year month day hour(midnight is zero) minute second milliseconds
DateTime dateTime5 = new DateTime(2000.1.1.0.0.0.0);
// 6. Generate a DateTime from another DateTime
DateTime dateTime6 = new DateTime(dateTime1);
// 7. Generate DateTime with time string
String timeString = "2019-01-01T00:00:00-06:00";
DateTime dateTime7 = DateTime.parse(timeString);
Copy the code
Local – the ReadablePartial
You can create a local time when the date or time you are dealing with in your program does not need to be a full moment, such as if you just want to focus on the year/month/day, or the time of day, or the day of the week. Joda Time – has said the Time is org. Joda Time. The ReadablePartial interface, realize its two classes LocalDate and LocalTime is respectively used to denote year/month/day and a Time of day.
// Explicitly provide each of the contained fields
LocalDate localDate = new LocalDate(2019.1.1);
// 6:30:06 PM
LocalTime localTime = new LocalTime(18.30.6.0);
Copy the code
LocalDate is replaced early Joda – Time version used in the org. Joda. Time. YearMonthDay, LocalTime is an early version of the org. Alternative. Joda Time. TimeOfDay. (all have been marked as outdated).
The time span
Joda-time provides three classes for representing Time spans (which can be useful in some business requirements).
- Duration
This class represents absolute precision in milliseconds and provides standard mathematical conversions while converting time spans to standard units.
- Period
This class representation is expressed in years, months and days.
- Interval
This class represents a specific time span and defines the scope of the time span with an explicit moment. Interval is a half-open Interval, so the time span encapsulated by Interval includes the start of the period but not the end of the period.
2.3.2 Using the joda-time method to process the Time
DateTime today = new DateTime();
// Get the time before 777 seconds
DateTime dateTime1 = today.minus(777 * 1000);
// Get the time for tomorrow
DateTime tomorrow = today.plusDays(1);
// Get the date of the first day of the month
DateTime dateTime2 = today.withDayOfMonth(1);
// Get the last day of the month three months after the current time
DateTime dateTime3 = today.plusMonths(3).dayOfMonth().withMaximumValue();
Copy the code
The following is a partial list of DateTime methods: Methods starting with plus/minus (plusDay, minusMonths, for example) : used to return instances that have been added or subtracted from a DateTime instance
-
Plus (long duration) increments the specified number of milliseconds and returns
-
PlusYears (int years) Adds the specified year and returns
-
PlusMonths (int months) Adds the specified month and returns the value
-
PlusWeeks (int weeks) adds the specified week and returns
-
PlusDays (int days) Adds the specified number of days and returns the value
-
PlusHours (int hours) increments the specified hour and returns
-
PlusMinutes (int minutes) Increments the specified minute and returns
-
PlusSeconds (int seconds) Increments the specified number of seconds and returns
-
PlusMillis (int millis) increments the specified millisecond and returns
On the contrary, the prefix plus is an increase and minus is a decrease
The with method is used to return the DateTime instance after the specified date unit has been updated
- WithCenturyOfEra (int centuryOfEra) Updates time century units and returns
- WithYearOfCentury (int yearOfCentury) Updates century year and returns
- WithYear (int year) Updates the time year and returns
- WithWeekyear (int weekyear) Update week and return
- WithMonthOfYear (int monthOfYear) Updates the month and returns
- WithDayOfYear (int dayOfYear) Updates the number of days and returns
- WithDayOfMonth (int dayOfMonth) Updates the number of days and returns
- WithDayOfWeek (int dayOfWeek) Number of days in which the update time is returned
- WithHourOfDay (int hour) Update time hour and returns
- WithMinuteOfHour (int minute) Specifies the update minute and returns
- WithSecondOfMinute (int second) Update time in seconds and returns
- Withmillisedersecond (int millis) returns the millisedersecond
- Withmillisederday (int millis) updates time in milliseconds and returns
- WithTimeAtStartOfDay () gets the earliest time of the day
Some operations to determine the size state of a DateTime object
- CompareTo (DateTime d) to compare two time size is greater than the specified time return 1 time less than a specified time return 1 equal returns 0
- Equals (DateTime d) compares whether two times are equal
- IsAfter (Long Instant) Checks whether the time is longer than the specified time
- IsAfterNow () checks whether the time is greater than the current time
- IsBefore (Long Instant) Checks whether the time is shorter than the specified time
- IsBeforeNow () Checks whether the time is smaller than the current time
- IsEqual (long instant) checks whether the time isEqual to the specified time
- IsEqualNow () checks whether the time is equal to the current time
2.3.3 Format the Time in joda-time mode
// The format template passed in only needs a format string compatible with JDK SimpleDateFormat
public static String convert(Date date,String dateFormat){
return new DateTime(date).toString(dateFormat);
}
// Convert Date in JDK to DateTime in UTC time zone
DateTime dateTime = new DateTime(new Date(), DateTimeZone.UTC);
// Convert String to 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();
}
Copy the code
Please refer to the official documentation for more information.
New time class library in JAVA 8
3.1 introduction
Due to the flaws and poor experience of previous JDK versions, and the influence of what has become the de facto standard joda-time, Oracle decided to provide high-quality date and Time support in the JAVA API. This is the new Time library in JDK 8 that incorporates most of the joda-time features. The authors of Joda-time were actually involved in the development and implemented all of JSR310. The new API is located under Java.time. Common classes include LocalDate, LocalTime, Instant, Duration, and Period.
Because the new Time library in JDK 8 borrowed a lot from the design and naming of Joda-time, if you’re a joda-time user, you can use the new API with no cost to learn (there are a few differences to note, of course).
3.2 Usage
3.2.1 Using LocalDate and LocalTime
The first is LocalDate. An instance of this class is an immutable object that provides a simple date with no information about the time of the day. Also, it doesn’t come with any time zone information.
// Create LocalDate with the specified date
LocalDate date = LocalDate.of(2019.1.1);
// Get the current date
LocalDate today = LocalDate.now();
// Get today's attributes
int year = date.getYear();
Month month = date.getMonth();
int day = date.getDayOfMonth();
DayOfWeek dow = date.getDayOfWeek();
int len = date.lengthOfMonth();
boolean leap = date.isLeapYear();
// Obtain the required attribute fields from the enumerated value of ChronoField
int year = date.get(ChronoField.YEAR);
Copy the code
Then there’s LocalTime, which represents a certain time of day.
LocalTime time = LocalTime.of(18.18.18);
int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();
Copy the code
Both LocalDate and LocalTime can be created by using the static method parse to parse the string.
LocalDate date = LocalDate.parse("2019-01-01");
LocalTime time = LocalTime.parse("18:18:18");
Copy the code
You can also pass a DateTimeFormatter to the parse method, an instance of which defines how to format a date or time object. It is a replacement for the older java.util.dateformat.
3.2.2 LocalDateTime
// Create LocalDateTime directly
LocalDateTime dt1 = LocalDateTime.of(2019, Month.JANUARY, 1.18.18.18);
// Merge the date and time
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);
// Extract LocalDate or LocalTime from LocalDateTime
LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();
Copy the code
3.3.3 Instant
The Instant class is designed to be understood by computers and represents a single large integer at a point in time that is actually computed in seconds (in nanoseconds) since the first Unix year (traditionally midnight on January 1, 1970, the UTC time zone).
// Pass an instance of the class that has been created in seconds
Instant.ofEpochSecond(3);
// Pass the number of seconds + nanoseconds after 2 seconds plus 1 million nanoseconds (1 second)
Instant.ofEpochSecond(2.1 _000_000_000);
Copy the code
3.3.4 Duration and Period
Duration is used to compare the time difference between two LocalTime objects or two Instant.
Duration d1 = Duration.between(time1, time2);
Duration d1 = Duration.between(dateTime1, dateTime2);
Duration d2 = Duration.between(instant1, instant2);
Copy the code
Period is used to compare multiple times in terms of years, months and days.
Period tenDays = Period.between(LocalDate.of(2019.1.1), lcalDate.of(2019.2.2));
Copy the code
Of course, both the Duration and Period classes provide a number of very convenient factory classes to create instances of directly.
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);
Copy the code
3.3.5 Manipulating, parsing, and formatting dates
// Use the withAttribute method directly
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);
Copy the code
All the classes declaring Temporal interface LocalDate, LocalTime, LocalDateTime and Instant, they all use get and with methods to distinguish the reading and modification of object value. If unsupported fields are used to access fields, Throws a UnsupportedTemporalTypeException anomalies. Similarly, the plus and minus methods are declared in the Temporal interface. By using these methods, adding or subtracting a number to TemporalUnit object, we can very conveniently move the Temporal object back or back to a certain time period. Through ChronoUnit enumeration, we can very conveniently implement the TemporalUnit interface.
3.3.6 More customized processing time
Pass a customized TemporalAdjuster object to the overloaded WITH method for more flexibility with dates. The Time and date API already provides a number of predefined TemporalAdjuster, which can be accessed through the Static factory method of the TemporalAdjuster class. The names of these methods are very intuitive, and the method name is the problem description. In some cases, if you need to define your own TemporalAdjuster, just declare the TemporalAdjuster interface and implement the corresponding method yourself.
LocalDate date1 = LocalDate.of(2014.3.18);
LocalDate date2 = date1.with(TemporalAdjuster.nextOrSame(DayOfWeek.SUNDAY));
LocalDate date3 = date2.with(TemporalAdjuster.lastDayOfMonth());
Copy the code
3.3.7 Parsing a date-time Object
Formatting and parsing date-time objects is another very important function in our daily work, and the new java.time.format package is designed specifically for this purpose. Of these, the most important class is the DateTimeFormatter. All instances of DateTimeFormatter can be used to create a string representing a particular date or time in a certain format. (All DateTimeFormatter instances are thread-safe in contrast to the old java.util.dateformat)
// Use different formatters to generate strings
LocalDate date = LocalDate.of(2019.1.1);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
// Generate a LocalDate object
LocalDate date1 = LocalDate.parse("20190101", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2019-01-01", DateTimeFormatter.ISO_LOCAL_DATE);
Copy the code
// Create a formatter with a specific schema
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);
Copy the code
3.3.8 Handling different time zones and calendar systems
In the new date-time library, a new java.time.ZoneId class (which, like other date and time classes, cannot be modified) replaces the java.util.TimeZone in order to minimize the complexity of dealing with time zones. A time zone is a region divided into the same standard time interval according to certain rules. The ZoneRules class contains 40 such instances. You can getRules for a specific time zone simply by calling getRules() of ZoneId. Each particular ZoneId object is identified by a region ID in the format {region}/{city}. Such as:
ZoneId romeZone = ZoneId.of("Asia/Shanghai");
Copy the code
Java 8 added a new method toZoneId to the original TimeZone, which converts an old TimeZone object to a ZoneId:
ZoneId zoneId = TimeZone.getDefault().toZoneId();
Copy the code
The resulting ZoneId object can be combined with LocalDate, LocalDateTime, or Instant to construct an instance of ZonedDateTime that represents a point in time relative to the specified time zone:
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);
Copy the code
With ZoneId, you can also convert LocalDateTime to Instant:
LocalDateTime dateTime = LocalDateTime.of(2019, Month.JANUARY, 18.13.45);
Instant instantFromDateTime = dateTime.toInstant(romeZone);
Copy the code
You can also get the LocalDateTime object in reverse:
Instant instant = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, romeZone);
Copy the code
Unlike joda-time, the date-time library in Java8 provides four other calendar systems, each of which has a corresponding logging class, They are ThaiBuddhistDate, MinguoDate, JapaneseDate and HijrahDate. All of these classes, as well as LocalDate, implement the ChronoLocalDate interface to model dates in the Gregorian calendar. With the LocalDate object, you can create instances of these classes. Also, using the static factory methods they provide, you can create instances of any Temporal object.
LocalDate date = LocalDate.of(2019, Month.JANUARY, 1);
JapaneseDate japaneseDate = JapaneseDate.from(date);
Copy the code
The resources
Joda-time introduces the Joda Time project and the java8 Time API
Dynamic computing time
Requirements: if it is 13:00, the time period is 15:10-17:10, 17:10-19:10, 19:10-21:10; That is, the earliest departure time is the current time + parameter [2h10min], and the latest time is the time when the start time is before 20:00 and the end time is after 20:00). How many time periods are there in total?
Analysis:
- Start time of the first time range: current time + parameter [2h10min], the intermediate time range is 2h;
- By understanding that the latest time range is a time range that starts before 20:00 and ends after 20:00, we can assume that the maximum time variable is Max
- Assuming that the current time is now and there are n periods in total, the formula can be derived:
now + (2h * n) + 10min <= max;
Note: all calculations are converted to milliseconds
public class Test {
/ / ms
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++) {
// Start time
// startTimestamp = startTimestamp + i * (120 * 60 * 1000);
// End time
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); }}}Copy the code
GitHub Org_Hejianhui /JavaStudy GitHub Hejianhui /JavaStudy