001/* 002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Stephane Lacoin 016 */ 017package org.nuxeo.apidoc.introspection; 018 019import java.text.ParseException; 020import java.text.SimpleDateFormat; 021import java.util.Calendar; 022import java.util.Date; 023import java.util.TimeZone; 024import java.util.regex.Matcher; 025import java.util.regex.Pattern; 026 027/** 028 * Contains code from Abdera to format dates. 029 */ 030public class DateTimeFormat { 031 032 /** 033 * Create the serialized string form from a java.util.Date 034 */ 035 public static String format(Date date) { 036 return abderaFormat(date); 037 } 038 039 /** 040 * Parse the serialized string form into a java.util.Date 041 * 042 * @param value The serialized string form of the date 043 * @return The created java.util.Date 044 */ 045 public static Date parse(String value) { 046 SimpleDateFormat formatter = new SimpleDateFormat(value.endsWith("Z") ? "yyyyMMdd'T'hhmmss'Z'" 047 : "yyyyMMdd'T'hhmmssZ"); 048 try { 049 return formatter.parse(value); 050 } catch (ParseException e) { 051 return abderaParse(value); 052 } 053 } 054 055 private static final Pattern PATTERN = Pattern.compile("(\\d{4})(?:-(\\d{2}))?(?:-(\\d{2}))?(?:[Tt](?:(\\d{2}))?(?::(\\d{2}))?(?::(\\d{2}))?(?:\\.(\\d{3}))?)?([Zz])?(?:([+-])(\\d{2}):(\\d{2}))?"); 056 057 public static String abderaFormat(Date date) { 058 StringBuilder sb = new StringBuilder(); 059 Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 060 c.setTime(date); 061 sb.append(c.get(Calendar.YEAR)); 062 sb.append('-'); 063 int f = c.get(Calendar.MONTH); 064 if (f < 9) { 065 sb.append('0'); 066 } 067 sb.append(f + 1); 068 sb.append('-'); 069 f = c.get(Calendar.DATE); 070 if (f < 10) { 071 sb.append('0'); 072 } 073 sb.append(f); 074 sb.append('T'); 075 f = c.get(Calendar.HOUR_OF_DAY); 076 if (f < 10) { 077 sb.append('0'); 078 } 079 sb.append(f); 080 sb.append(':'); 081 f = c.get(Calendar.MINUTE); 082 if (f < 10) { 083 sb.append('0'); 084 } 085 sb.append(f); 086 sb.append(':'); 087 f = c.get(Calendar.SECOND); 088 if (f < 10) { 089 sb.append('0'); 090 } 091 sb.append(f); 092 sb.append('.'); 093 f = c.get(Calendar.MILLISECOND); 094 if (f < 100) { 095 sb.append('0'); 096 } 097 if (f < 10) { 098 sb.append('0'); 099 } 100 sb.append(f); 101 sb.append('Z'); 102 return sb.toString(); 103 } 104 105 public static Date abderaParse(String value) { 106 Matcher m = PATTERN.matcher(value); 107 if (m.find()) { 108 Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 109 int hoff = 0, moff = 0, doff = -1; 110 if (m.group(9) != null) { 111 doff = m.group(9).equals("-") ? 1 : -1; 112 hoff = doff * (m.group(10) != null ? Integer.parseInt(m.group(10)) : 0); 113 moff = doff * (m.group(11) != null ? Integer.parseInt(m.group(11)) : 0); 114 } 115 c.set(Calendar.YEAR, Integer.parseInt(m.group(1))); 116 c.set(Calendar.MONTH, m.group(2) != null ? Integer.parseInt(m.group(2)) - 1 : 0); 117 c.set(Calendar.DATE, m.group(3) != null ? Integer.parseInt(m.group(3)) : 1); 118 c.set(Calendar.HOUR_OF_DAY, m.group(4) != null ? Integer.parseInt(m.group(4)) + hoff : 0); 119 c.set(Calendar.MINUTE, m.group(5) != null ? Integer.parseInt(m.group(5)) + moff : 0); 120 c.set(Calendar.SECOND, m.group(6) != null ? Integer.parseInt(m.group(6)) : 0); 121 c.set(Calendar.MILLISECOND, m.group(7) != null ? Integer.parseInt(m.group(7)) : 0); 122 return c.getTime(); 123 } else { 124 throw new IllegalArgumentException("Invalid Date Format"); 125 } 126 } 127 128}