001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.bridge.util.xml;
011:
012: import javax.xml.xpath.*;
013:
014: import java.util.*;
015:
016: import org.mmbase.bridge.*;
017:
018: import org.mmbase.util.logging.Logger;
019: import org.mmbase.util.logging.Logging;
020:
021: /**
022: * Dates are stored as integer in mmbase. If you want to show these dates
023: * in a nice format in the XSL transformation.
024: * it is necessary to use this Xalan extension.
025: * The XSLT looks like this then:
026: *
027: * <pre>
028: * <xsl:stylesheet version = "1.0"
029: * xmlns:xsl ="http://www.w3.org/1999/XSL/Transform"
030: * xmlns:date ="org.mmbase.bridge.util.xml.DateFormat"
031: * >
032: * </pre>
033: *
034: * @author Nico Klasens
035: * @author Martijn Houtman
036: * @author Michiel Meeuwissen
037: * @version $Id: DateFormat.java,v 1.15 2007/04/09 19:10:27 michiel Exp $
038: * @since MMBase-1.7
039: */
040: public class DateFormat {
041:
042: private static final Logger log = Logging
043: .getLoggerInstance(DateFormat.class);
044:
045: /**
046: * TimeZone null or blank means server timezone. If timeZone is not
047: * recognized it will fall back to GMT.
048: * @param timeZone String representation of a timezine
049: * @return TimeZone object or the default timezone when id does not exist
050: */
051: private static TimeZone getTimeZone(String timeZone) {
052: if (timeZone == null || "".equals(timeZone.trim())) {
053: return TimeZone.getDefault();
054: } else {
055: TimeZone tz = TimeZone.getTimeZone(timeZone);
056: if (!tz.getID().equals(timeZone)) {
057: tz = TimeZone.getDefault();
058: }
059: return tz;
060: }
061: }
062:
063: /**
064: * Formats a node's field value with the date pattern
065: * @param number the number or alias of the node containing the field
066: * @param fieldName the name of the field to format
067: * @param pattern the date pattern (i.e. 'dd-MM-yyyy')
068: * @param timeZone timezone of the field value
069: * @param language Language of the field value
070: * @param country country of the field value
071: * @return the formatted string
072: */
073: public static String format(String number, String fieldName,
074: String pattern, String timeZone, String language,
075: String country) {
076: return format("mmbase", number, fieldName, pattern, timeZone,
077: language, country);
078: }
079:
080: /**
081: * Formats a node's field value with the date pattern
082: * @param cloudName the name of the cloud in which to find the node
083: * @param number the number or alias of the node containing the field
084: * @param fieldName the name of the field to format
085: * @param pattern the date pattern (i.e. 'dd-MM-yyyy')
086: * @param timeZone timezone of the field value
087: * @param language Language of the field value
088: * @param country country of the field value
089: * @return the formatted string
090: */
091: public static String format(String cloudName, String number,
092: String fieldName, String pattern, String timeZone,
093: String language, String country) {
094: try {
095: Cloud cloud = LocalContext.getCloudContext().getCloud(
096: cloudName);
097: cloud.setLocale(new Locale(language, country));
098: return format(cloud, number, fieldName, pattern, timeZone);
099: } catch (BridgeException e) {
100: return "could not find '" + fieldName + "' on node '"
101: + number + "' (" + e.toString() + ")";
102: }
103: }
104:
105: /**
106: * Formats a node's field value with the date pattern
107: * @param cloud the cloud in which to find the node
108: * @param number the number or alias of the node containing the field
109: * @param fieldName the name of the field to format
110: * @param pattern the date pattern (i.e. 'dd-MM-yyyy')
111: * @param timeZone timezone of the field value
112: * @return the formatted string
113: */
114: public static String format(Cloud cloud, String number,
115: String fieldName, String pattern, String timeZone) {
116: try {
117: Node node = cloud.getNode(number);
118: String fieldValue = "" + node.getIntValue(fieldName);
119: return format(fieldValue, pattern, 1000, timeZone, cloud
120: .getLocale());
121: } catch (BridgeException e) {
122: if (log.isDebugEnabled()) {
123: log.debug("could not find '" + fieldName
124: + "' on node '" + number + "'");
125: log.trace(Logging.stackTrace(e));
126: }
127: return "could not find " + fieldName + " on node " + number
128: + "(" + e.toString() + ")";
129: }
130: }
131:
132: /**
133: * Formats the fieldvalue to a date pattern
134: *
135: * @param fieldValue time-stamp in seconds
136: * @param pattern the date pattern (i.e. 'dd-MM-yyyy')
137: * @param timeZone timezone of the field value
138: * @param language Language of the field value
139: * @param country country of the field value
140: * @return the formatted string
141: */
142: public static String format(String fieldValue, String pattern,
143: String timeZone, String language, String country) {
144: return format(fieldValue, pattern, 1000, timeZone, language,
145: country);
146: }
147:
148: /** Formats the fieldvalue to a date pattern
149: *
150: * @param fieldValue time-stamp
151: * @param pattern the date pattern (i.e. 'dd-MM-yyyy')
152: * @param factor Factor to multiply fieldvalue to make milliseconds. Should be 1000 normally (so field in seconds)
153: * @param timeZone Timezone. Null or blank means server timezone. If not recognized it will fall back to GMT.
154: * @param language The language for which the date must be formatted.
155: * @param country The country for which the date must be formatted.
156: * @return the formatted string
157: */
158: public static String format(String fieldValue, String pattern,
159: int factor, String timeZone, String language, String country) {
160: return format(fieldValue, pattern, factor, timeZone,
161: new Locale(language, country));
162: }
163:
164: /**
165: * @param fieldValue time-stamp
166: * @param pattern the date pattern (i.e. 'dd-MM-yyyy')
167: * @param factor Factor to multiply fieldvalue to make milliseconds. Should be 1000 normally (so field in seconds)
168: * @param timeZone Timezone. Null or blank means server timezone. If not recognized it will fall back to GMT.
169: * @param locale The locale for which the date must be formatted.
170: * @return the formatted String
171: */
172: protected static String format(String fieldValue, String pattern,
173: int factor, String timeZone, Locale locale) {
174: if (fieldValue == null || "".equals(fieldValue)) {
175: return "";
176: }
177: java.text.DateFormat df = org.mmbase.util.DateFormats
178: .getInstance(pattern, timeZone, locale);
179: long seconds = Long.valueOf(fieldValue).longValue();
180: return df.format(new Date(seconds * factor));
181: }
182:
183: /**
184: * Formats a node's field value with the date pattern.
185: * This version requires you to supply a DOM node. It will search for a tag of the form
186: * <field name='number' > and uses it's contents to retrieve the node.
187: * @deprecated not sure where this is used?
188: * @param cloud the cloud in which to find the node
189: * @param node A DOM node (xml) containing the node's fields as subtags
190: * @param fieldName the name of the field to format
191: * @param pattern the date pattern (i.e. 'dd-MM-yyyy')
192: * @param timeZone The timezone of the field value
193: * @return the formatted string
194: * @throws javax.xml.transform.TransformerException if something went wrong while searching the DOM Node
195: */
196: public static String format(Cloud cloud, org.w3c.dom.Node node,
197: String fieldName, String pattern, String timeZone)
198: throws XPathExpressionException {
199: log.debug("calling with dom node");
200: // bit of a waste to use an xpath here?
201: XPath xpath = XPathFactory.newInstance().newXPath();
202: String number = xpath.evaluate("./field[@name='number']", node);
203: return format(cloud, number, fieldName, pattern, timeZone);
204: }
205:
206: /** Returns the year part of the date
207: *
208: * @param fieldValue time-stamp
209: * @return year part
210: */
211: public static int getYear(String fieldValue) {
212: return getDatePart(fieldValue, 1000, Calendar.YEAR, "");
213: }
214:
215: /** Returns the month part of the date
216: *
217: * @param fieldValue time-stamp
218: * @return month part
219: */
220: public static int getMonth(String fieldValue) {
221: return getDatePart(fieldValue, 1000, Calendar.MONTH, "") + 1;
222: }
223:
224: /** Returns the day of the month part of the date
225: *
226: * @param fieldValue time-stamp
227: * @return day of the month part
228: */
229: public static int getDay(String fieldValue) {
230: return getDatePart(fieldValue, 1000, Calendar.DAY_OF_MONTH, "");
231: }
232:
233: /** Returns the hours part of the date
234: *
235: * @param fieldValue time-stamp
236: * @return hours part
237: */
238: public static int getHours(String fieldValue) {
239: return getDatePart(fieldValue, 1000, Calendar.HOUR_OF_DAY, "");
240: }
241:
242: /** Returns the minutes part of the date
243: *
244: * @param fieldValue time-stamp
245: * @return minutes part
246: */
247: public static int getMinutes(String fieldValue) {
248: return getDatePart(fieldValue, 1000, Calendar.MINUTE, "");
249: }
250:
251: /** Returns the seconds part of the date
252: *
253: * @param fieldValue time-stamp
254: * @return seconds part
255: */
256: public static int getSeconds(String fieldValue) {
257: return getDatePart(fieldValue, 1000, Calendar.SECOND, "");
258: }
259:
260: /** Returns the year part of the date
261: *
262: * @param fieldValue time-stamp
263: * @param timeZone timezone
264: * @return year part
265: */
266: public static int getYear(String fieldValue, String timeZone) {
267: return getDatePart(fieldValue, 1000, Calendar.YEAR, timeZone);
268: }
269:
270: /** Returns the month part of the date
271: *
272: * @param fieldValue time-stamp
273: * @param timeZone timezone
274: * @return month part
275: */
276: public static int getMonth(String fieldValue, String timeZone) {
277: return getDatePart(fieldValue, 1000, Calendar.MONTH, timeZone) + 1;
278: }
279:
280: /** Returns the day of the month part of the date
281: *
282: * @param fieldValue time-stamp
283: * @param timeZone timezone
284: * @return day of the month part
285: */
286: public static int getDay(String fieldValue, String timeZone) {
287: return getDatePart(fieldValue, 1000, Calendar.DAY_OF_MONTH,
288: timeZone);
289: }
290:
291: /** Returns the hours part of the date
292: *
293: * @param fieldValue time-stamp
294: * @param timeZone timezone
295: * @return hours part
296: */
297: public static int getHours(String fieldValue, String timeZone) {
298: return getDatePart(fieldValue, 1000, Calendar.HOUR_OF_DAY,
299: timeZone);
300: }
301:
302: /** Returns the minutes part of the date
303: *
304: * @param fieldValue time-stamp
305: * @param timeZone timezone
306: * @return minutes part
307: */
308: public static int getMinutes(String fieldValue, String timeZone) {
309: return getDatePart(fieldValue, 1000, Calendar.MINUTE, timeZone);
310: }
311:
312: /** Returns the seconds part of the date
313: *
314: * @param fieldValue time-stamp
315: * @param timeZone timezone
316: * @return seconds part
317: */
318: public static int getSeconds(String fieldValue, String timeZone) {
319: return getDatePart(fieldValue, 1000, Calendar.SECOND, timeZone);
320: }
321:
322: /** Returns the a part of the date
323: *
324: * @param fieldValue time-stamp
325: * @param factor Factor to multiply fieldvalue to make milliseconds. Should be 1000 normally (so field in seconds)
326: * @param datePart which part of the date should be returned. These are Calendar constants
327: * @return a part
328: */
329: public static int getDatePart(String fieldValue, int factor,
330: int datePart) {
331: return getDatePart(fieldValue, factor, datePart, "");
332: }
333:
334: /** Returns the a part of the date
335: *
336: * @param fieldValue time-stamp
337: * @param factor Factor to multiply fieldvalue to make milliseconds. Should be 1000 normally (so field in seconds)
338: * @param datePart which part of the date should be returned. These are Calendar constants
339: * @param timeZone Timezone. Null or blank means server timezone. If not recognized it will fall back to GMT.
340: * @return a part
341: */
342: public static int getDatePart(String fieldValue, int factor,
343: int datePart, String timeZone) {
344: if (fieldValue != null && !"".equals(fieldValue.trim())) {
345: Calendar cal = Calendar.getInstance(getTimeZone(timeZone));
346: long seconds = Long.valueOf(fieldValue).longValue();
347: cal.setTimeInMillis(seconds * factor);
348: return cal.get(datePart);
349: } else {
350: return -1;
351: }
352: }
353:
354: }
|