All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pojava.datetime.DateTimeFormat Maven / Gradle / Ivy

Go to download

POJava is a simple, light-weight Java-based library providing a variety of utilities for data transformation.

There is a newer version: 3.0.3
Show newest version
package org.pojava.datetime;

import java.text.DateFormatSymbols;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

/*
 Copyright 2010 John Pile

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/**
 * DateTimeFormat formats a DateTime object as a String according to a template. This class
 * provides similar functionality to Java's SimpleDateFormat class, with some notable
 * differences. It changes the meaning of the "S" character from "millisecond" to
 * "fractional second" so that, for example, nine consecutive "S" characters would represent
 * nanoseconds, while three "S" characters represent milliseconds. The upper-case "G" still
 * represents "BC" or "AD", but I added a lower-cased "g" to the format to use "BCE" or "CE".
 * While "Z" still shows time zone offset as "-HHmm", "ZZ" will add a colon, as "-HH:mm".
 * 
 * Because it does not "compile" the format String, DateTimeFormat can provide a static method
 * with the same performance as a constructed object. It does allow a constructed object for
 * similar behavior to existing formatters, but there is no performance advantage in doing so.
 * In either case, this class is thread-safe, provided your application is not trying to
 * change the internals of Java's TimeZone object as you're using it.
 * 
 * It is important to understand that the default behavior is to format the output according to
 * the system's time zone. If you want to format the output according to the DateTime object's
 * internal time zone, then pass the time zone as a parameter. For example,
 * 
 * 
 * DateTimeFormat("yyyy-MM-dd", dateTimeObj, dateTimeObj.getTimezone);
 * 
* * For this version, you're kind of stuck with an English-only version of dates. I'll be * revising that at a future date. * * @author John Pile * */ public class DateTimeFormat { private static final int[] dom = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; private String template; private static Map symbols=new HashMap(); public DateTimeFormat(String template) { this.template = template; } public String format(DateTime dt) { return format(this.template, dt); } public String format(long millis) { return format(this.template, new DateTime(millis)); } public static String format(String template, long millis) { return format(template, new DateTime(millis)); } public static String format(String template, DateTime dt) { return format(template, dt, TimeZone.getDefault()); } public static String format(String template, DateTime dt, TimeZone tz) { return format(template, dt, tz, Locale.getDefault()); } public static String format(String template, DateTime dt, TimeZone tz, Locale loc) { Tm tm = new Tm(dt, tz); StringBuilder sb = new StringBuilder(); StringBuilder word = new StringBuilder(); char[] fmt = template.toCharArray(); char prior = fmt[0]; if (prior!='\'') { word.append(prior); } if (!symbols.containsKey(loc)) { symbols.put(loc, new DateFormatSymbols(loc)); } DateFormatSymbols dfs=symbols.get(loc); boolean isLiteral=(prior=='\''); for (int i = 1; i < fmt.length; i++) { if (fmt[i]=='\'') { if (prior=='\'') { sb.append('\''); } else { appendWord(sb, word, tm, dt, tz, loc, dfs); } word.setLength(0); prior = prior=='\'' ? ' ' : '\''; isLiteral=!isLiteral; } else if (isLiteral) { sb.append(fmt[i]); prior=fmt[i]; } else if (fmt[i] == prior) { word.append(prior); } else { appendWord(sb, word, tm, dt, tz, loc, dfs); prior = fmt[i]; word.setLength(0); word.append(prior); } } appendWord(sb, word, tm, dt, tz, loc, dfs); return sb.toString(); } private static void appendWord(StringBuilder sb, StringBuilder word, Tm tm, DateTime dt, TimeZone tz, Locale loc, DateFormatSymbols dfs) { if (word.length()==0) { return; } char c = word.charAt(0); int len = word.length(); switch (c) { case 'g': sb.append(tm.getYear() < 0 ? "BCE" : "CE"); break; case 'G': sb.append(tm.getYear() < 0 ? "BC" : "AD"); break; case 'y': sb.append(zfill(tm.getYear(), Math.max(2, len))); break; case 'M': if (len > 3) { sb.append(dfs.getMonths()[tm.getMonth()-1]); } else if (len == 3) { sb.append(dfs.getShortMonths()[tm.getMonth()-1]); } else if (len == 2) { sb.append(zfill(tm.getMonth(), 2)); } else { sb.append(tm.getMonth()); } break; case 'D': if (len > 1) { sb.append(zfill(dom[tm.getMonth()] + tm.getDay() + leapDays(tm), len)); } else { sb.append(dom[tm.getMonth()] + tm.getDay() + leapDays(tm)); } break; case 'd': if (len > 1) { sb.append(zfill(tm.getDay(), len)); } else { sb.append(tm.getDay()); } break; case 'E': if (len > 3) { sb.append(dfs.getWeekdays()[tm.getWeekday()-1]); } else { sb.append(dfs.getShortWeekdays()[tm.getWeekday()-1]); } break; case 'a': sb.append(dfs.getAmPmStrings()[tm.getHour() > 11 ? 1 : 0]); break; case 'H': if (len > 1) { sb.append(zfill(tm.getHour(), len)); } else { sb.append(tm.getHour()); } break; case 'k': if (len > 1) { sb.append(zfill(1 + tm.getHour(), len)); } else { sb.append(1 + tm.getHour()); } break; case 'K': if (len > 1) { sb.append(zfill(tm.getHour() % 12, len)); } else { sb.append(tm.getHour() % 12); } break; case 'h': int hr = tm.getHour() % 12; if (hr == 0) hr = 12; if (len > 1) { sb.append(zfill(hr, len)); } else { sb.append(hr); } break; case 'm': if (len > 1) { sb.append(zfill(tm.getMinute(), len)); } else { sb.append(tm.getMinute()); } break; case 's': if (len > 1) { sb.append(zfill(tm.getSecond(), len)); } else { sb.append(tm.getSecond()); } break; case 'S': sb.append(zfill(tm.getNanosecond(), 9).substring(0, len)); break; case 'z': if (len>3) { sb.append(dt.timeZone().getDisplayName(loc)); } else { sb.append(tz.getDisplayName(tz.inDaylightTime(dt.toDate()), TimeZone.SHORT, loc)); } break; case 'Z': int minutes = tz.getOffset(dt.toMillis()) / 60000; if (minutes < 0) { sb.append('-'); minutes = -minutes; } else { sb.append('+'); } int hours = minutes / 60; minutes -= hours * 60; if (hours<10){ sb.append('0'); } sb.append(hours); if (len>1) { sb.append(':'); } if (minutes<10) { sb.append('0'); } sb.append(minutes); break; default: sb.append(word); break; } } private static String zfill(int value, int size) { StringBuilder zeros = new StringBuilder("000000000000"); zeros.append(Integer.toString(value)); return zeros.substring(zeros.length() - Math.min(zeros.length(), size)); } private static int leapDays(Tm tm) { if (tm.getMonth() < 3) { return 0; } int year = tm.getYear(); return year % 4 == 0 && (year % 400 == 0 || year % 100 != 0) ? 1 : 0; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy