001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client.ui.input.datebox; 029 030import org.opencms.gwt.client.Messages; 031 032import java.util.Date; 033 034import com.google.gwt.i18n.client.DateTimeFormat; 035 036/** 037 * This class is an Helper with mostly static methods that convert a given date object 038 * or that convert a given String.<p> 039 */ 040public final class CmsDateConverter { 041 042 /** A constant for am. */ 043 public static final String AM = "am"; 044 045 /** A constant for pm. */ 046 public static final String PM = "pm"; 047 048 /** The part of the 12 hour presentation which signals the am pm. */ 049 private static final String AMPM_PATTERN_PART = "aa"; 050 051 /** A pattern for date representation. */ 052 private static final String DATE_PATTERN = Messages.get().key(Messages.GUI_DATEBOX_DATE_PATTERN_0); 053 054 /** A pattern for date time representation. */ 055 private static final String DATETIME_PATTERN = Messages.get().key(Messages.GUI_DATEBOX_DATETIME_PATTERN_0); 056 057 /** A pattern for time representation. */ 058 private static final String TIME_PATTERN = Messages.get().key(Messages.GUI_DATEBOX_TIME_PATTERN_0); 059 060 /** The formatter for the date format. */ 061 private static final DateTimeFormat Z_DATE_FORMAT = DateTimeFormat.getFormat(DATE_PATTERN); 062 063 /** The format used to parse dates (this needs to be different from Z_DATE_FORMAT because we want to interpret the year 22 as 2022, but don't want to format 1922 as 22. */ 064 private static final DateTimeFormat Z_DATE_FORMAT_SHORTYEAR = DateTimeFormat.getFormat( 065 DATE_PATTERN.replace("yyyy", "yy")); 066 067 /** The formatter for the date time format. */ 068 private static final DateTimeFormat Z_DATETIME_FORMAT = DateTimeFormat.getFormat(DATETIME_PATTERN); 069 070 /** The format used to parse date/time combinations (this needs to be different from Z_DATETIME_FORMAT because we want to interpret the year 22 as 2022, but don't want to format 1922 as 22. */ 071 private static final DateTimeFormat Z_DATETIME_FORMAT_SHORTYEAR = DateTimeFormat.getFormat( 072 DATETIME_PATTERN.replace("yyyy", "yy")); 073 074 /** The formatter for the time format. */ 075 private static final DateTimeFormat Z_TIME_FORMAT = DateTimeFormat.getFormat(TIME_PATTERN); 076 077 /** 078 * Hiding constructor for final class.<p> 079 */ 080 private CmsDateConverter() { 081 082 // nothing to do 083 } 084 085 /** 086 * Cuts the suffix (am or pm) from a given time String.<p> 087 * 088 * If the given String has less than 5 characters an dosen't 089 * contains an am or pm in it the original String is returned.<p> 090 * 091 * @param time the time String to cut the suffix from 092 * 093 * @return the time String without the suffix or the original String if the format of the String is incorrect 094 */ 095 public static String cutSuffix(String time) { 096 097 String ret = time.toLowerCase(); 098 if (ret.toLowerCase().contains(CmsDateConverter.AM) || ret.toLowerCase().contains(CmsDateConverter.PM)) { 099 if (ret.length() > 5) { 100 ret = ret.replace(CmsDateConverter.AM, ""); 101 ret = ret.replace(CmsDateConverter.PM, ""); 102 ret = ret.trim(); 103 } 104 } 105 return ret; 106 } 107 108 /** 109 * Formats the provided date to a date only representation.<p> 110 * 111 * @param date the date to format 112 * 113 * @return the formatted date as a string 114 */ 115 public static String dateToString(final Date date) { 116 117 String result; 118 if (date == null) { 119 result = ""; 120 } else { 121 result = Z_DATE_FORMAT.format(date); 122 } 123 return result; 124 } 125 126 /** 127 * Merges a given Date object with a given time String.<p> 128 * 129 * Returns a <code>null</code> if the given time format coudn't be parsed.<p> 130 * 131 * The expected time String should include the am pm information if the time format is in 12 hour presentation.<p> 132 * 133 * @param date the given Date object which time has to be set 134 * @param time the given time String which should be inserted into the Date Object 135 * 136 * @return the merged date Object 137 */ 138 @SuppressWarnings("deprecation") 139 public static Date getDateWithTime(Date date, String time) { 140 141 return getDateWithTime(date, time, Z_TIME_FORMAT); 142 } 143 144 /** 145 * Changes the time portion of date to another value. 146 * 147 * @param date the original date 148 * @param time the string representing the time to be set in the result 149 * @param timeFormat the format to use for parsing the time 150 * 151 * @return a new Date with the date from the date parameter and the time from the time parameter. 152 */ 153 public static Date getDateWithTime(Date date, String time, DateTimeFormat timeFormat) { 154 155 Date result; 156 try { 157 Date timeAsDate = timeFormat.parse(time); 158 result = new Date(date.getYear(), date.getMonth(), date.getDate()); 159 result.setHours(timeAsDate.getHours()); 160 result.setMinutes(timeAsDate.getMinutes()); 161 result.setSeconds(timeAsDate.getSeconds()); 162 } catch (Exception e) { 163 result = null; 164 } 165 return result; 166 167 } 168 169 /** 170 * Returns the short time format of a given date as String.<p> 171 * 172 * @param date the date to get the short time format from 173 * 174 * @return the short time format of a given date 175 */ 176 public static String getTime(Date date) { 177 178 return Z_TIME_FORMAT.format(date); 179 } 180 181 /** 182 * Returns <code>true</code> if the current date format is in the 12 hour 183 * representation mode <code>false</code> otherwise.<p> 184 * 185 * @return <code>true</code> if an am or a pm is in a new Date object <code>false</code> otherwise 186 */ 187 public static boolean is12HourPresentation() { 188 189 return DATETIME_PATTERN.toLowerCase().contains(AMPM_PATTERN_PART); 190 } 191 192 /** 193 * Returns <code>true</code> if an am is in the given date object <code>false</code> otherwise.<p> 194 * 195 * @param date the date to check 196 * 197 * @return <code>true</code> if an am is in the given Date object <code>false</code> otherwise 198 */ 199 public static boolean isAm(Date date) { 200 201 String time = getTime(date); 202 return time.toLowerCase().contains(AM); 203 } 204 205 /** 206 * Parses the provided String as a date.<p> 207 * 208 * First try to parse the String with the given time format.<p> 209 * 210 * If that fails try to parse the date with the browser settings.<p> 211 * 212 * @param dateText the string representing a date 213 * 214 * @return the date created, or null if there was a parse error 215 * 216 * @throws Exception in case the text can not be parsed to a date 217 */ 218 public static Date toDate(final String dateText) throws Exception { 219 220 Date date = null; 221 if (dateText.length() > 0) { 222 date = Z_DATETIME_FORMAT_SHORTYEAR.parse(dateText.trim()); 223 if (!validateDate(date)) { 224 throw new IllegalArgumentException(); 225 } 226 } 227 return date; 228 } 229 230 /** 231 * Formats the provided date as only a date format (dd/mm/yyyy). Note, a null date is a possible input. 232 * 233 * @param date the date to format 234 * 235 * @return the formatted date as a string 236 */ 237 public static String toDateString(final Date date) { 238 239 String result; 240 if (date == null) { 241 result = ""; 242 } else { 243 result = Z_DATE_FORMAT.format(date); 244 } 245 return result; 246 } 247 248 /** 249 * Parses the provided String as a date.<p> 250 * 251 * First try to parse the String with the given time format.<p> 252 * 253 * If that fails try to parse the date with the browser settings.<p> 254 * 255 * @param dateText the string representing a date 256 * 257 * @return the date created, or null if there was a parse error 258 * 259 * @throws Exception in case the text can not be parsed to a date 260 */ 261 public static Date toDayDate(final String dateText) throws Exception { 262 263 Date date = null; 264 if (dateText.length() > 0) { 265 date = Z_DATE_FORMAT_SHORTYEAR.parse(dateText.trim()); 266 } 267 return date; 268 } 269 270 /** 271 * Formats the provided date. Note, a null date is a possible input. 272 * 273 * @param date the date to format 274 * 275 * @return the formatted date as a string 276 */ 277 public static String toString(final Date date) { 278 279 String result; 280 if (date == null) { 281 result = ""; 282 } else { 283 result = Z_DATETIME_FORMAT.format(date); 284 } 285 return result; 286 } 287 288 /** 289 * Validates a time String if it matches one of the two regular expressions.<p> 290 * 291 * Returns <code>true</code> if the given date matches to one of the regular 292 * expressions, <code>false</code> otherwise.<p> 293 * 294 * @param date the date String to check 295 * 296 * @return <code>true</code> if the given time matches to one of the regular expressions, <code>false</code> otherwise 297 */ 298 public static boolean validateDate(Date date) { 299 300 String time = getTime(date); 301 boolean timeOk = validateTime(time); 302 return timeOk; 303 304 } 305 306 /** 307 * Validates a time String if it matches the regular expressions.<p> 308 * 309 * Returns <code>true</code> if the given time matches the regular 310 * expressions, <code>false</code> otherwise.<p> 311 * 312 * @param time the time String to check 313 * 314 * @return <code>true</code> if the given time matches the regular expressions, <code>false</code> otherwise 315 */ 316 public static native boolean validateTime(String time) /*-{ 317 var hasMeridian = false; 318 var re = /^\d{1,2}[:]\d{2}([:]\d{2})?( [aApP][mM]?)?$/; 319 if (!re.test(time)) { 320 return false; 321 } 322 if (time.toLowerCase().indexOf("p") != -1) { 323 hasMeridian = true; 324 } 325 if (time.toLowerCase().indexOf("a") != -1) { 326 hasMeridian = true; 327 } 328 var values = time.split(":"); 329 if ((parseFloat(values[0]) < 0) || (parseFloat(values[0]) > 23)) { 330 return false; 331 } 332 if (hasMeridian) { 333 if ((parseFloat(values[0]) < 1) || (parseFloat(values[0]) > 12)) { 334 return false; 335 } 336 } 337 if ((parseFloat(values[1]) < 0) || (parseFloat(values[1]) > 59)) { 338 return false; 339 } 340 if (values.length > 2) { 341 if ((parseFloat(values[2]) < 0) || (parseFloat(values[2]) > 59)) { 342 return false; 343 } 344 } 345 return true; 346 }-*/; 347}