/*
* Smart GWT (GWT for SmartClient)
* Copyright 2008 and beyond, Isomorphic Software, Inc.
*
* Smart GWT is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 3
* is published by the Free Software Foundation. Smart GWT is also
* available under typical commercial license terms - see
* http://smartclient.com/license
*
* This software 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
* Lesser General Public License for more details.
*/
package com.smartgwt.client.data;
import com.google.gwt.core.client.JavaScriptObject;
import com.smartgwt.client.core.DataClass;
import com.smartgwt.client.types.RelativeDateRangePosition;
import com.smartgwt.client.util.EnumUtil;
import com.smartgwt.client.util.JSOHelper;
/**
* This class is used used to specify a datetime offset within SmartGWT, for example for use in the
* {@link com.smartgwt.client.widgets.form.fields.RelativeDateItem} class.
* <P>
* The value attribute is set to a string which specifies the offset from some base date (typically
* the current date as returned from a call to <code>new Date();</code>).
* See {@link #RelativeDate(String)} for details on the expected format of the string passed in.
*
* @see com.smartgwt.client.data.DateRange#setRelativeStartDate(RelativeDate)
* @see com.smartgwt.client.data.DateRange#setRelativeEndDate(RelativeDate)
*/
public class RelativeDate extends DataClass {
private RelativeDateRangePosition rangePosition;
private String value;
/**
* Builtin option for this moment - equivalent to calling
* <code>new RelativeDate(RelativeDateShortcut.NOW);</code>
*/
public static RelativeDate NOW = new RelativeDate("$now");
/**
* Builtin option for the start of today
*/
public static RelativeDate TODAY = new RelativeDate("$today");
/**
* Builtin option for the start of today (same as {@link #TODAY})
*/
public static RelativeDate START_OF_TODAY = new RelativeDate("$startOfToday");
/**
* Builtin option for the end of today (one millisecond before the {@link #START_OF_TODAY}
*/
public static RelativeDate END_OF_TODAY = new RelativeDate("$endOfToday");
/**
* Builtin option for the start of yesterday
*/
public static RelativeDate YESTERDAY = new RelativeDate("$yesterday");
/**
* Builtin option for the start of yesterday (same as {@link #YESTERDAY})
*/
public static RelativeDate START_OF_YESTERDAY = new RelativeDate("$startOfYesterday");
/**
* Builtin option for the end of yesterday (one millisecond before the {@link #START_OF_YESTERDAY})
*/
public static RelativeDate END_OF_YESTERDAY = new RelativeDate("$endOfYesterday");
/**
* Builtin option for the start of tomorrow
*/
public static RelativeDate TOMORROW = new RelativeDate("$tomorrow");
/**
* Builtin option for the start of tomorrow (same as {@link #TOMORROW})
*/
public static RelativeDate START_OF_TOMORROW = new RelativeDate("$startOfTomorrow");
/**
* Builtin option for the end of tomorrow (one millisecond before the {@link #START_OF_TOMORROW})
*/
public static RelativeDate END_OF_TOMORROW = new RelativeDate("$endOfTomorrow");
/**
* Builtin option for the current day of the previous week
*/
public static RelativeDate WEEK_AGO = new RelativeDate("$weekAgo");
/**
* Builtin option for the current day of the following week
*/
public static RelativeDate WEEK_FROM_NOW = new RelativeDate("$weekFromNow");
/**
* Builtin option for the current day of the previous month
*/
public static RelativeDate MONTH_AGO = new RelativeDate("$monthAgo");
/**
* Builtin option for the current day of the following month
*/
public static RelativeDate MONTH_FROM_NOW = new RelativeDate("$monthFromNow");
/**
* Builtin option for the start of the current week
*/
public static RelativeDate START_OF_WEEK = new RelativeDate("$startOfWeek");
/**
* Builtin option for the end of the current week
*/
public static RelativeDate END_OF_WEEK = new RelativeDate("$endOfWeek");
/**
* Builtin option for this moment
*/
public static RelativeDate START_OF_MONTH = new RelativeDate("$startOfMonth");
/**
* Builtin option for the end of the current month
*/
public static RelativeDate END_OF_MONTH = new RelativeDate("$endOfMonth");
/**
* Builtin option for the start of the current year
*/
public static RelativeDate START_OF_YEAR = new RelativeDate("$startOfYear");
/**
* Builtin option for the end of the current year
*/
public static RelativeDate END_OF_YEAR = new RelativeDate("$endOfYear");
/**
* The value attribute of a RelativeDate object is a string that should be specified in one of 2 formats:
* <P>
* There are a number of standard preset shortcut date-offset strings. These include the following
* <ul>
* <li> $now - this moment </li>
* <li> $today - the current day. By default this resolves to the start of the current day though
* an explicit +link{RelativeDateRangePosition} may be used to specify the end of the current day.</li>
* <li> $startOfToday - the start of today</li>
* <li> $endOfToday - the end of today (one millisecond before the $startOfTomorrow) </li>
* <li> $yesterday - the previous day.</li>
* <li> $startOfYesterday - the start of yesterday</li>
* <li> $endOfYesterday - the end of yesterday (one millisecond before the $startOfToday) </li>
* <li> $tomorrow - the following day</li>
* <li> $startOfTomorrow - the start of tomorrow </li>
* <li> $endOfTomorrow - the end of tomorrow </li>
* <li> $startOfWeek - the start of the current week </li>
* <li> $endOfWeek - the end of the current week </li>
* <li> $startOfMonth - the start of the current month </li>
* <li> $endOfMonth - the end of the current month </li>
* <li> $startOfYear - the start of the current year </li>
* <li> $endOfYear - the end of the current year </li>
* </ul>
* Note that some shortcuts indicate a time period but do not directly indicate whether the value
* refers to the start or end of the time period in question. This
* ambiguity can be resolved by specifying an explicit RelativeDateRangePosition when calling APIs
* that convert from RelativeDates to absolute date values. This is the case for <i>$today</i>,
* <i>$tomorrow</i>, <i>$yesterday</i>, <i>$weekAgo</i>, <i>$weekFromNow</i>, <i>$monthAgo</i>
* and <i>$monthFromNow</i>. If a range position is not explicitly passed, these will all default
* to the start of the day in question.
* <P>
* Alternatively the value can be a special RelativeDateString comprised of the following parts:
* <ul>
* <li>direction: the direction in which the quantity applies - one of + or - </li>
* <li>quantity: the number of units of time to apply - a number </li>
* <li>timeUnit: an abbreviated timeUnit to use - one of ms/MS (millisecond), s/S (second),
* mn/MN (minute), h/H (hour), d/D (day), w/W (week), m/M (month), q/Q (quarter, 3-months),
* y/Y (year), dc/DC (decade) or c/C (century). <br>
* The timeUnit is case sensitive. A lowercase timeUnit implies an exact offset, so <code>+1d</code>
* refers to the current date / time increased by exactly 24 hours. If the timeUnit is
* uppercase, it refers to the start or end boundary of the period of time in question, so
* <code>+1D</code> would refer to the end of the day (23:39:59:999) tomorrow, and
* <code>-1D</code> would refer to the start of the day (00:00:00:000) yesterday.</li>
* <li>[qualifier]: an optional timeUnit encapsulated in square-brackets and used to offset
* the calculation - eg. if +1d is "plus one day", +1d[W] is "plus one day from the
* end of the current week". You may also specify another complete RelativeDateString as the
* [qualifier], which offers more control - eg, +1d[+1W] indicates "plus one day from
* the end of NEXT week".</li>
* </ul>
* <P>
* This format is very flexible. Here are a few example relative date strings:<br>
* <code>+0D</code>: End of today. There are often multiple ways to represent the same time
* using this system - for example this could also be written as <code>-1ms[+1D]</code><br>
* <code>-0D</code>: Beginning of today.<br>
* <code>+1W</code>: End of next week.<br>
* <code>+1ms[+0W]</code>: Beginning of next week.<br>
* <code>+1w[-0D]</code>: Beginning of the current day of next week.
*
* @param value string representation of the relative date
*/
public RelativeDate(String value) {
//TODO add regex based assert to validate base syntax, along supported with built in types
this.value = value;
}
public RelativeDate(RelativeDateRangePosition rangePosition, String value) {
this(value);
this.rangePosition = rangePosition;
}
public RelativeDate(JavaScriptObject jsObj) {
super(jsObj);
rangePosition = EnumUtil.getEnum(RelativeDateRangePosition.values(), JSOHelper.getAttribute(jsObj, "rangePosition"));
value = JSOHelper.getAttribute(jsObj, "value");
}
public final RelativeDateRangePosition getRangePosition() {
return rangePosition;
}
/**
* @return the string representation of the relative date
* @see #RelativeDate(String)
*/
public final String getValue() {
return value;
}
private static native String mapRelativeDateShortcut(String relativeDateString, String rangePosition)/*-{
return $wnd.isc.DateUtil.mapRelativeDateShortcut(relativeDateString, rangePosition);
}-*/;
@Override
public JavaScriptObject getJsObj() {
JavaScriptObject jsObj = JavaScriptObject.createObject();
JSOHelper.setAttribute(jsObj, "_constructor", "RelativeDate");
if (rangePosition != null) {
JSOHelper.setAttribute(jsObj, "rangePosition", rangePosition.getValue());
}
JSOHelper.setAttribute(jsObj, "value", mapRelativeDateShortcut(value, rangePosition == null ? null : rangePosition.getValue()));
return jsObj;
}
}