com.hfg.datetime.DateUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.datetime;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.hfg.units.TimeUnit;
import com.hfg.util.StringBuilderPlus;
import com.hfg.util.collection.OrderedMap;
//------------------------------------------------------------------------------
/**
Date-related utility functions.
@author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class DateUtil
{
/**
ISO 8601 datetime format. Ex: 2001-07-04T12:08:56.235-07:00
See http://www.w3.org/TR/NOTE-datetime.
Not thread-safe on its own.
*/
// Shim for Java 6. Java 7 adds the 'X' formatting char in place of 'Z' for timezone offsets containing a colon.
public static final SimpleDateFormat W3CDTF_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") {
public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos) {
String fix = super.format(date, toAppendTo, pos).toString();
fix = fix.substring(0, fix.length()-2) + ":" + fix.substring(fix.length()-2, fix.length());
return new StringBuffer().append(fix);
};
};
private static Pattern sEscapeSequence = Pattern.compile("[^\\\\]((?:\\\\\\S)+)");
private static Map sPhpSubstitutionMap = new OrderedMap<>(35);
static
{
sPhpSubstitutionMap.put("d", "dd");
sPhpSubstitutionMap.put("D", "EEE");
sPhpSubstitutionMap.put("j", "d");
sPhpSubstitutionMap.put("l", "E");
sPhpSubstitutionMap.put("N", "u");
sPhpSubstitutionMap.put("S", "");
sPhpSubstitutionMap.put("w", "");
sPhpSubstitutionMap.put("z", "D");
sPhpSubstitutionMap.put("W", "w");
sPhpSubstitutionMap.put("M", "MMM");
sPhpSubstitutionMap.put("F", "M");
sPhpSubstitutionMap.put("m", "MM");
sPhpSubstitutionMap.put("n", "MM");
sPhpSubstitutionMap.put("t", "");
sPhpSubstitutionMap.put("L", "");
sPhpSubstitutionMap.put("Y", "YYYY");
sPhpSubstitutionMap.put("o", "YYYY");
sPhpSubstitutionMap.put("y", "YY");
sPhpSubstitutionMap.put("a", "a");
sPhpSubstitutionMap.put("A", "a");
sPhpSubstitutionMap.put("g", "h");
sPhpSubstitutionMap.put("H", "HH");
sPhpSubstitutionMap.put("G", "H");
sPhpSubstitutionMap.put("h", "hh");
sPhpSubstitutionMap.put("i", "mm");
sPhpSubstitutionMap.put("s", "ss");
sPhpSubstitutionMap.put("u", "SSS");
sPhpSubstitutionMap.put("Z", "");
sPhpSubstitutionMap.put("O", "Z");
sPhpSubstitutionMap.put("P", "XXX");
sPhpSubstitutionMap.put("T", "z");
sPhpSubstitutionMap.put("c", "");
sPhpSubstitutionMap.put("C", "");
sPhpSubstitutionMap.put("U", "");
}
//##########################################################################
// PUBLIC METHODS
//##########################################################################
//--------------------------------------------------------------------------
public static synchronized Date threadsafeParse(String inDateString, SimpleDateFormat inFormat)
throws ParseException
{
return inFormat.parse(inDateString);
}
//--------------------------------------------------------------------------
public static String generateElapsedTimeString(long inStartTime)
{
return generateElapsedTimeString(inStartTime, System.currentTimeMillis());
}
//--------------------------------------------------------------------------
public static int getCurrentYear()
{
return new GregorianCalendar().get(Calendar.YEAR);
}
//--------------------------------------------------------------------------
public static Date roundToNextMinute(Date inStartTime)
{
Calendar calendar = new GregorianCalendar();
calendar.setTime(inStartTime);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.add(Calendar.MINUTE, 1);
return calendar.getTime();
}
//--------------------------------------------------------------------------
public static Date roundToNextHour(Date inStartTime)
{
Calendar calendar = new GregorianCalendar();
calendar.setTime(inStartTime);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.add(Calendar.HOUR_OF_DAY, 1);
return calendar.getTime();
}
//--------------------------------------------------------------------------
public static String generateElapsedTimeString(long inStartTime, long inEndTime)
{
long elapsedMillis = inEndTime - inStartTime;
long elapsedSec = 0;
long elapsedMin = 0;
long elapsedHour = 0;
String output;
if (elapsedMillis >= TimeUnit.second.getMilliseconds())
{
elapsedSec = elapsedMillis / TimeUnit.second.getMilliseconds();
if (elapsedSec >= 60)
{
elapsedMin = elapsedSec / 60;
elapsedSec = elapsedSec % 60;
if (elapsedMin >= 60)
{
elapsedHour = elapsedMin / 60;
elapsedMin = elapsedMin % 60;
}
}
output = String.format("%02d:%02d:%02d", elapsedHour, elapsedMin, elapsedSec);
}
else
{
output = String.format("00:00:00.%03d", elapsedMillis);
}
return output;
}
//--------------------------------------------------------------------------
public static String getISO_8601_Date()
{
return getISO_8601_Date(new Date());
}
//--------------------------------------------------------------------------
public static String getISO_8601_Date(Date inValue)
{
return new SimpleDateFormat("yyyy-MM-dd").format(inValue);
}
//--------------------------------------------------------------------------
public static String getYYYYMMDD()
{
return getYYYYMMDD(new Date());
}
//--------------------------------------------------------------------------
public static String getYYYYMMDD(Date inValue)
{
return new SimpleDateFormat("yyyyMMdd").format(inValue);
}
//--------------------------------------------------------------------------
public static String getYYYY_MM(Date inValue, char inSeparator)
{
return new SimpleDateFormat("yyyy" + inSeparator + "MM").format(new Date());
}
//--------------------------------------------------------------------------
public static String getYYYY_MM_DD()
{
return new SimpleDateFormat("yyyy.MM.dd").format(new Date());
}
//--------------------------------------------------------------------------
public static String getYYYY_MM_DD_HH_mm_aa()
{
return getYYYY_MM_DD_HH_mm_aa(new Date());
}
//--------------------------------------------------------------------------
public static String getYYYY_MM_DD_HH_mm_aa(Date inDate)
{
return new SimpleDateFormat("yyyy.MM.dd HH:mm aa").format(inDate);
}
//--------------------------------------------------------------------------
public static String getYYYY_MM_DD_HH_mm_ss()
{
return getYYYY_MM_DD_HH_mm_aa(new Date());
}
//--------------------------------------------------------------------------
public static String getYYYY_MM_DD_HH_mm_ss(Date inDate)
{
return new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(inDate);
}
//--------------------------------------------------------------------------
/**
Makes a best attempt to convert php date format syntax into Java data format syntax.
Not all specifiers are supported.
@param inPhpFormatString the date format in php synatx
@return a SimpleDateFormat object
*/
public static SimpleDateFormat getFormatterUsingPhpSyntax(String inPhpFormatString)
{
/*
Format Description Example returned values
------ ----------------------------------------------------------------------- -----------------------
d Day of the month, 2 digits with leading zeros 01 to 31
D A short textual representation of the day of the week Mon to Sun
j Day of the month without leading zeros 1 to 31
l A full textual representation of the day of the week Sunday to Saturday
N ISO-8601 numeric representation of the day of the week 1 (for Monday) through 7 (for Sunday)
S English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
w Numeric representation of the day of the week 0 (for Sunday) to 6 (for Saturday)
z The day of the year (starting from 0) 0 to 364 (365 in leap years)
W ISO-8601 week number of year, weeks starting on Monday 01 to 53
F A full textual representation of a month, such as January or March January to December
m Numeric representation of a month, with leading zeros 01 to 12
M A short textual representation of a month Jan to Dec
n Numeric representation of a month, without leading zeros 1 to 12
t Number of days in the given month 28 to 31
L Whether it's a leap year 1 if it is a leap year, 0 otherwise.
o ISO-8601 year number (identical to (Y), but if the ISO week number (W) Examples: 1998 or 2004
belongs to the previous or next year, that year is used instead)
Y A full numeric representation of a year, 4 digits Examples: 1999 or 2003
y A two digit representation of a year Examples: 99 or 03
a Lowercase Ante meridiem and Post meridiem am or pm
A Uppercase Ante meridiem and Post meridiem AM or PM
g 12-hour format of an hour without leading zeros 1 to 12
G 24-hour format of an hour without leading zeros 0 to 23
h 12-hour format of an hour with leading zeros 01 to 12
H 24-hour format of an hour with leading zeros 00 to 23
i Minutes, with leading zeros 00 to 59
s Seconds, with leading zeros 00 to 59
u Decimal fraction of a second Examples:
(minimum 1 digit, arbitrary number of digits allowed) 001 (i.e. 0.001s) or
100 (i.e. 0.100s) or
999 (i.e. 0.999s) or
999876543210 (i.e. 0.999876543210s)
O Difference to Greenwich time (GMT) in hours and minutes Example: +1030
P Difference to Greenwich time (GMT) with colon between hours and minutes Example: -08:00
T Timezone abbreviation of the machine running the code Examples: EST, MDT, PDT ...
Z Timezone offset in seconds (negative if west of UTC, positive if east) -43200 to 50400
c ISO 8601 date represented as the local time with an offset to UTC appended.
Notes: Examples:
1) If unspecified, the month / day defaults to the current month / day, 1991 or
the time defaults to midnight, while the timezone defaults to the 1992-10 or
browser's timezone. If a time is specified, it must include both hours 1993-09-20 or
and minutes. The "T" delimiter, seconds, milliseconds and timezone 1994-08-19T16:20+01:00 or
are optional. 1995-07-18T17:21:28-02:00 or
2) The decimal fraction of a second, if specified, must contain at 1996-06-17T18:22:29.98765+03:00 or
least 1 digit (there is no limit to the maximum number 1997-05-16T19:23:30,12345-0400 or
of digits allowed), and may be delimited by either a '.' or a ',' 1998-04-15T20:24:31.2468Z or
Refer to the examples on the right for the various levels of 1999-03-14T20:24:32Z or
date-time granularity which are supported, or see 2000-02-13T21:25:33
http://www.w3.org/TR/NOTE-datetime for more info. 2001-01-12 22:26:34
C An ISO date string as implemented by the native Date object's 1962-06-17T09:21:34.125Z
[Date.toISOString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
method. This outputs the numeric part with *UTC* hour and minute
values, and indicates this by appending the `'Z'` timezone
identifier.
U Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) 1193432466 or -2138434463
MS Microsoft AJAX serialized dates \/Date(1238606590509)\/ (i.e. UTC milliseconds since epoch) or
\/Date(1238606590509+0800)\/
time A javascript millisecond timestamp 1350024476440
timestamp A UNIX timestamp (same as U) 1350024866
*/
StringBuilderPlus buffer = new StringBuilderPlus(inPhpFormatString);
// Note that the order of replacement is important
for (String target : sPhpSubstitutionMap.keySet())
{
String replacement = sPhpSubstitutionMap.get(target);
int index;
int fromIndex = 0;
while ((index = buffer.indexOf(target, fromIndex)) >= 0)
{
if (0 == index
|| getEscapeCount(buffer, index)%2 != 1) // Escaped characters indicated static text in the php format
{
buffer.replace(index, index + target.length(), replacement);
fromIndex = index + replacement.length();
}
else
{
fromIndex++;
}
}
}
// Replace escaped characters (php syntax) with a single-quoted version (Java syntax)
Matcher m = sEscapeSequence.matcher(buffer);
int fromIndex = 0;
while (m.find(fromIndex))
{
String strippedValue = m.group(1).replaceAll("\\\\", "");
buffer.replace(m.start() + 1, m.end(), "'" + strippedValue + "'");
}
return new SimpleDateFormat(buffer.toString());
}
//--------------------------------------------------------------------------
// Returns the number of '\' characters that preceded the character at the specified index
private static int getEscapeCount(CharSequence inString, int inIndex)
{
int count = 0;
for (int i = inIndex - 1; i >= 0; i--)
{
if (inString.charAt(i) == '\\')
{
count++;
}
else
{
break;
}
}
return count;
}
}