/* * * * Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program 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 * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */ package com.sun.j2me.global; import java.util.Calendar; import java.util.TimeZone; import javax.microedition.global.Formatter; /** * <code>DateTimeFormat</code> is a concrete class for formatting dates in a * locale-sensitive manner. It allows for formatting (date -> text). <p> * * <code>DateTimeFormat</code> allows you to start by choosing one of * predefined patterns for date-time formatting passing appropriate style to * factory method <code>getInstance(style, locale)</code>. * <table> * * <tr> * * <td> * a * </td> * * <td> * am/pm * </td> * * </tr> * * <tr> * * <td> * H * </td> * * <td> * hour in day 0-23 * </td> * * </tr> * * <tr> * * <td> * h * </td> * * <td> * hour in am/pm 0-11 * </td> * * </tr> * * <tr> * * <td> * K * </td> * * <td> * hour in day 1-24 * </td> * * </tr> * * <tr> * * <td> * k * </td> * * <td> * hour in am/pm 1-12 * </td> * * </tr> * * <tr> * * <td> * m * </td> * * <td> * minute 0-59 * </td> * * </tr> * * <tr> * * <td> * s * </td> * * <td> * second 0-59 * </td> * * </tr> * * <tr> * * <td> * d * </td> * * <td> * day in month (number) * </td> * * </tr> * * <tr> * * <td> * dd * </td> * * <td> * day in month (number 2 digits) * </td> * * </tr> * * <tr> * * <td> * EE * </td> * * <td> * day in week short "Mon" * </td> * * </tr> * * <tr> * * <td> * EEEE * </td> * * <td> * day in week long "Monday" * </td> * * </tr> * * <tr> * * <td> * M * </td> * * <td> * month in year (number) * </td> * * </tr> * * <tr> * * <td> * MM * </td> * * <td> * month in year (number 2 digits) * </td> * * </tr> * * <tr> * * <td> * MMM * </td> * * <td> * month in year short "Oct" * </td> * * </tr> * * <tr> * * <td> * MMMM * </td> * * <td> * month in year long "October" * </td> * * </tr> * * <tr> * * <td> * yy * </td> * * <td> * year short "05" * </td> * * </tr> * * <tr> * * <td> * yyyy * </td> * * <td> * year long "2005" * </td> * * </tr> * * <tr> * * <td> * G * </td> * * <td> * era * </td> * * </tr> * * <tr> * * <td> * z * </td> * * <td> * timezone * </td> * * </tr> * * </table> * * */ public class DateTimeFormat { /** * Holds initialized instance of <code>DateFormatSymbols</code> which * encapsulate locale-dependent information like names of days in week, * months etc. */ private DateFormatSymbols symbols; /** * Style of date/time formatting. * * @see Formatter#TIME_LONG * @see Formatter#TIME_SHORT * @see Formatter#DATE_LONG * @see Formatter#DATE_SHORT * @see Formatter#DATETIME_LONG * @see Formatter#DATETIME_SHORT */ private int style; /** * Creates new <code>DateTimeFormat</code> object. It is assumed that * <code>style</code> contains correct value and <code>symbols</code> * refers to properly initialized <code>DateFormatSymbols</code> object. * * @param style predefined date/time style * @param symbols object encapsulating localized DateTime symbols */ public DateTimeFormat(int style, DateFormatSymbols symbols) { this.style = style; this.symbols = symbols; } /** * Formats date/time with the current <code>style</code>. * * @param calendar date/time to format * @param nf integer instance of <code>NumberFormat</code> to * perform formatting of integer date and time values * @return formatted string */ protected String format(Calendar calendar, NumberFormat nf) { StringBuffer appendTo = new StringBuffer(); StringBuffer pattern = new StringBuffer(symbols.patterns[style]); nf.setGroupingUsed(false); char c; int value; int digits; if (style == Formatter.DATETIME_SHORT) { // date first paremeter, time second pattern = new StringBuffer(MessageFormat.format( symbols.patterns[style], new String[] {symbols.patterns[Formatter.DATE_SHORT], symbols.patterns[Formatter.TIME_SHORT]})); } else if (style == Formatter.DATETIME_LONG) { pattern = new StringBuffer(MessageFormat.format( symbols.patterns[style], new String[] {symbols.patterns[Formatter.DATE_LONG], symbols.patterns[Formatter.TIME_LONG]})); } for (int i = 0; i < pattern.length(); i++) { c = pattern.charAt(i); switch (c) { case 'a': // AM or PM symbol int ampm = calendar.get(Calendar.AM_PM); appendTo.append(symbols.ampms[ampm == Calendar.AM ? 0 : 1]); break; case 'H': // Hours in 24-hour mode 0 - based value = calendar.get(Calendar.HOUR_OF_DAY); digits = ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'H') ? 2 : 1; nf.setMinimumIntegerDigits(digits); appendTo.append(nf.format(value)); i += digits - 1; break; case 'h': // Hours in 12-hour mode, 1 - based value = calendar.get(Calendar.HOUR); digits = ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'h') ? 2 : 1; nf.setMinimumIntegerDigits(digits); appendTo.append(nf.format(value)); i += digits - 1; break; case 'K': // Hours in 12-hour mode 0 - based value = calendar.get(Calendar.HOUR_OF_DAY); value = value>12 ? value % 12 : value; // noon is 12 midnight is 0 digits = ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'K') ? 2 : 1; nf.setMinimumIntegerDigits(digits); appendTo.append(nf.format(value)); i += digits - 1; break; case 'k': // Hours in 24-hour mode 1 based value = calendar.get(Calendar.HOUR_OF_DAY); value = (value == 0) ? 24 : value; digits = ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'k') ? 2 : 1; nf.setMinimumIntegerDigits(digits); appendTo.append(nf.format(value)); i += digits - 1; break; case 'm': // Minutes value = calendar.get(Calendar.MINUTE); digits = ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'm') ? 2 : 1; nf.setMinimumIntegerDigits(digits); appendTo.append(nf.format(value)); i += digits - 1; break; case 's': // Seconds value = calendar.get(Calendar.SECOND); digits = ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 's') ? 2 : 1; nf.setMinimumIntegerDigits(digits); appendTo.append(nf.format(value)); i += digits - 1; break; case 'E': // Long or short weekday name if ((i + 3) < pattern.length() && pattern.charAt(i + 1) == 'E' && pattern.charAt(i + 2) == 'E' && pattern.charAt(i + 3) == 'E') { // long day of week name value = calendar.get(Calendar.DAY_OF_WEEK); appendTo.append(symbols.weekDays[value]); i += 3; } else if ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'E') { // short day of week name value = calendar.get(Calendar.DAY_OF_WEEK); appendTo.append(symbols.shortWeekDays[value]); i += 1; } break; case 'd': // Numeric day of month if ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'd') { // numeric day 2 digits value = calendar.get(Calendar.DAY_OF_MONTH); nf.setMinimumIntegerDigits(2); appendTo.append(nf.format(value)); i += 1; } else { // numeric day 1 digit value = calendar.get(Calendar.DAY_OF_MONTH); nf.setMinimumIntegerDigits(1); appendTo.append(nf.format(value)); } break; case 'M': // Long or short month name or numeric month if ((i + 3) < pattern.length() && pattern.charAt(i + 1) == 'M' && pattern.charAt(i + 2) == 'M' && pattern.charAt(i + 3) == 'M') { // long month name value = calendar.get(Calendar.MONTH); appendTo.append(symbols.months[value]); i += 3; } else if ((i + 2) < pattern.length() && pattern.charAt(i + 1) == 'M' && pattern.charAt(i + 2) == 'M') { // short month name value = calendar.get(Calendar.MONTH); appendTo.append(symbols.shortMonths[value]); i += 2; } else if ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'M') { value = calendar.get(Calendar.MONTH) + 1; nf.setMinimumIntegerDigits(2); appendTo.append(nf.format(value)); i += 1; } else { value = calendar.get(Calendar.MONTH) + 1; nf.setMinimumIntegerDigits(1); appendTo.append(nf.format(value)); } break; case 'y': // Long or short year value = calendar.get(Calendar.YEAR); if ((i + 3) < pattern.length() && pattern.charAt(i + 1) == 'y' && pattern.charAt(i + 2) == 'y' && pattern.charAt(i + 3) == 'y') { // long year nf.setMinimumIntegerDigits(4); appendTo.append(nf.format(value)); i += 3; } else if ((i + 1) < pattern.length() && pattern.charAt(i + 1) == 'y') { // short year nf.setMinimumIntegerDigits(2); String y = nf.format(value); appendTo.append(y.substring(y.length() - 2, y.length())); i += 1; } break; /* * case 'G': // not in midp * value = calendar.get(Calendar.ERA); * appendTo.append(symbols.eras[value]); * break; */ case 'z': // Time zone TimeZone tzone = calendar.getTimeZone(); if (tzone == null) { break; } int offset = tzone.getRawOffset(); if (offset == 0) { appendTo.append('Z'); } else { offset /= 3600000; if (offset >= 0) { appendTo.append('+'); } else { appendTo.append('-'); offset = -offset; } if (offset < 10) { appendTo.append('0'); } appendTo.append(offset); appendTo.append(":00"); } break; default: appendTo.append(c); } } // for return appendTo.toString(); } }