All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.snowflake.common.core.SFDate Maven / Gradle / Ivy

There is a newer version: 5.1.4
Show newest version
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.snowflake.common.core;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
 * Represents dates without time.
 *
 * Used to store dates, as in 'midnights'.
 *
 * Stores UTC midnights always for a given date.
 * 
 * Instances of this class are immutable.
 *
 * @author mzukowski
 */
public class SFDate extends SFInstant
{
  private final Date date;

  /**
   * Return the embedded Java date object
   * @return Date instance
   */
  public Date getDate()
  {
    return date;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int hashCode()
  {
    return date.hashCode();
  }

  /**
   * Return the number of milliseconds since UTC epoch
   * @return milliseconds
   */
  public long getTime()
  {
    return date.getTime();
  }

  /**
   * Construct a string that can be safely passed to XP.
   * @return UTC string
   */
  public String toUTCString()
  {
    Calendar calendar = CalendarCache.get("UTC");
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    df.setCalendar(calendar);
    return df.format(date.getTime());
  }

  /**
   * Compare if we're smaller than, equal to, or larger than the other SFDate
   * @param other target SFDate
   * @return value lower than 0 if we're smaller,
   *         0 if we're equal,
   *         value larger than 0 if we're larger.
   */
  public int compareTo(SFDate other)
  {
    return date.compareTo(other.date);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean equals(Object o)
  {
    if (o == null || !(o instanceof SFDate))
    {
      return false;
    }
    return equals((SFDate) o);
  }

  /**
   * Returns if we're equal to the other SFDate
   * @param other target SFDate
   * @return true if identical otherwise false
   */
  public boolean equals(SFDate other)
  {
    return date.equals(other.date);
  }

  /**
   * Constructor using UTC milliseconds
   * @param millis epoch time in UTC in milliseconds
   */
  public SFDate(long millis)
  {
    date = normalize(millis, null);
  }

  /**
   * Constructor using Java Date
   * @param date date instance
   */
  public SFDate(Date date)
  {
    if (date == null)
    {
      throw new IllegalArgumentException(
              "Illegal null date parameter.");
    }
    this.date = normalize(date.getTime(), null);
  }
  
  /**
   * Copy constructor.
   * Unless an explicit copy of {@code original} is needed, use of this
   * constructor is unnecessary since SFDates are immutable.
   * @param sfd SFDate instance
   */
  public SFDate(SFDate sfd)
  {
    // object is immutable, date is always set
    this.date = (Date)sfd.date.clone();
  }

  /**
   * Utility function generating a new SFDate from a given SFTimestamp.
   * @param timestamp source timestamp
   * @return SFDate instance
   */
  public static SFDate fromTimestamp(SFTimestamp timestamp)
  {
    long millis = timestamp.getTime();
    TimeZone tz = timestamp.getTimeZone();
    return new SFDate(normalize(millis, tz));
  }

  /**
   * Normalize the timestamp to midnight on that date
   * @param millis epoch time
   * @param tz timezone
   * @return java.util.Date
   */
  private static Date normalize(long millis, TimeZone tz)
  {
    if (tz != null)
    { // Get the same time as local time but in UTC
      millis += tz.getOffset(millis);
    }
    // Then, compute the midnight before. Double is precise enough
    final double MILLIS_IN_DAY = 24 * 3600 * 1000;
    double dblMS = millis;
    // It's critical we round down (negative infinity) to get midnight.
    dblMS = Math.floor(dblMS / MILLIS_IN_DAY) * MILLIS_IN_DAY;
    millis = (long) dblMS;
    return new Date(millis);
  }

  /**
   * Extract a particular component of a date.
   * @param field  field id as specified in the Calendar class
   * @param optWeekStart  Optional WEEK_START value
   * @param optWoyPolicy  Optional WEEK_OF_YEAR_POLICY value
   * @return value
   */
  @Override
  public int extract(int field, Integer optWeekStart, Integer optWoyPolicy)
  {
    return extract(field, SFInstant.GMT, date.getTime(), optWeekStart, optWoyPolicy);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String toString()
  {
    return "SFDate(date='" + date + "')";
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy