/**
 * Copyright(c) 2014 ABB Switzerland Ltd.
 *
 * Periodic interval functions
 */
import { TimeUnit } from "./basics";
import * as basics from "./basics";
import { DateTime } from "./datetime";
import { Duration } from "./duration";
/**
 * Specifies how the period should repeat across the day
 * during DST changes.
 */
export declare enum PeriodDst {
    /**
     * Keep repeating in similar intervals measured in UTC,
     * unaffected by Daylight Saving Time.
     * E.g. a repetition of one hour will take one real hour
     * every time, even in a time zone with DST.
     * Leap seconds, leap days and month length
     * differences will still make the intervals different.
     */
    RegularIntervals = 0,
    /**
     * Ensure that the time at which the intervals occur stay
     * at the same place in the day, local time. So e.g.
     * a period of one day, referenceing at 8:05AM Europe/Amsterdam time
     * will always reference at 8:05 Europe/Amsterdam. This means that
     * in UTC time, some intervals will be 25 hours and some
     * 23 hours during DST changes.
     * Another example: an hourly interval will be hourly in local time,
     * skipping an hour in UTC for a DST backward change.
     */
    RegularLocalTime = 1,
    /**
     * End-of-enum marker
     */
    MAX = 2
}
/**
 * Convert a PeriodDst to a string: "regular intervals" or "regular local time"
 * @throws timezonecomplete.Argument.P for invalid PeriodDst value
 */
export declare function periodDstToString(p: PeriodDst): string;
/**
 * Repeating time period: consists of a reference date and
 * a time length. This class accounts for leap seconds and leap days.
 */
export declare class Period {
    /**
     * Allow not using instanceof
     */
    kind: string;
    /**
     * Reference moment of period
     */
    private _reference;
    /**
     * Interval
     */
    private _interval;
    /**
     * DST handling
     */
    private _dst;
    /**
     * Normalized reference date, has day-of-month <= 28 for Monthly
     * period, or for Yearly period if month is February
     */
    private _intReference;
    /**
     * Normalized interval
     */
    private _intInterval;
    /**
     * Normalized internal DST handling. If DST handling is irrelevant
     * (because the reference time zone does not have DST)
     * then it is set to RegularInterval
     */
    private _intDst;
    /**
     * Constructor
     * LIMITATION: if dst equals RegularLocalTime, and unit is Second, Minute or Hour,
     * then the amount must be a factor of 24. So 120 seconds is allowed while 121 seconds is not.
     * This is due to the enormous processing power required by these cases. They are not
     * implemented and you will get an assert.
     *
     * @param reference The reference date of the period. If the period is in Months or Years, and
     *                  the day is 29 or 30 or 31, the results are maximised to end-of-month.
     * @param interval The interval of the period
     * @param dst Specifies how to handle Daylight Saving Time. Not relevant
     *            if the time zone of the reference datetime does not have DST.
     *            Defaults to RegularLocalTime.
     * @throws timezonecomplete.Argument.Dst for invalid dst value
     * @throws timezonecomplete.Argument.Interval if amount not positive integer
     * @throws timezonecomplete.Argument.Interval.NotImplemented if dst=RegularLocalTime and the interval is not a multiple of one day
     */
    constructor(reference: DateTime, interval: Duration, dst?: PeriodDst);
    /**
     * Constructor
     * LIMITATION: if dst equals RegularLocalTime, and unit is Second, Minute or Hour,
     * then the amount must be a factor of 24. So 120 seconds is allowed while 121 seconds is not.
     * This is due to the enormous processing power required by these cases. They are not
     * implemented and you will get an assert.
     *
     * @param reference The reference of the period. If the period is in Months or Years, and
     *                  the day is 29 or 30 or 31, the results are maximised to end-of-month.
     * @param amount The amount of units.
     * @param unit The unit.
     * @param dst Specifies how to handle Daylight Saving Time. Not relevant
     *              if the time zone of the reference datetime does not have DST.
     *              Defaults to RegularLocalTime.
     * @throws timezonecomplete.Argument.Amount for invalid amount
     * @throws timezonecomplete.Argument.Unit for invalid time unit
     * @throws timezonecomplete.Argument.Interval if amount not positive integer
     * @throws timezonecomplete.Argument.Interval.NotImplemented if dst=RegularLocalTime and the interval is not a multiple of one day
     * @throws timezonecomplete.Argument.Dst for invalid dst value
     */
    constructor(reference: DateTime, amount: number, unit: TimeUnit, dst?: PeriodDst);
    /**
     * Constructor
     * LIMITATION: if dst equals RegularLocalTime, and unit is Second, Minute or Hour,
     * then the amount must be a factor of 24. So 120 seconds is allowed while 121 seconds is not.
     * This is due to the enormous processing power required by these cases. They are not
     * implemented and you will get an assert.
     *
     * @param json period represented as JSON object
     * @throws timezonecomplete.Argument.Json for invalid JSON (missing reference, unparseable reference or interval)
     * @throws timezonecomplete.Argument.Interval if amount not positive integer
     * @throws timezonecomplete.Argument.Interval.NotImplemented if dst=RegularLocalTime and the interval is not a multiple of one day
     */
    constructor(json: PeriodJson);
    /**
     * Return a fresh copy of the period
     * @throws nothing
     */
    clone(): Period;
    /**
     * The reference date
     * @throws nothing
     */
    reference(): DateTime;
    /**
     * DEPRECATED: old name for the reference date
     * @throws nothing
     */
    start(): DateTime;
    /**
     * The interval
     * @throws nothing
     */
    interval(): Duration;
    /**
     * The amount of units of the interval
     * @throws nothing
     */
    amount(): number;
    /**
     * The unit of the interval
     * @throws nothing
     */
    unit(): TimeUnit;
    /**
     * The dst handling mode
     * @throws nothing
     */
    dst(): PeriodDst;
    /**
     * The first occurrence of the period greater than
     * the given date. The given date need not be at a period boundary.
     * Pre: the fromdate and reference date must either both have timezones or not
     * @param fromDate: the date after which to return the next date
     * @return the first date matching the period after fromDate, given in the same zone as the fromDate.
     * @throws timezonecomplete.UnawareToAwareConversion if not both fromdate and the reference date are both aware or unaware of time zone
     * @throws timezonecomplete.NotFound.Zone if the UTC time zone doesn't exist in the time zone database
     */
    findFirst(fromDate: DateTime): DateTime;
    /**
     * Returns the next timestamp in the period. The given timestamp must
     * be at a period boundary, otherwise the answer is incorrect.
     * This function has MUCH better performance than findFirst.
     * Returns the datetime "count" times away from the given datetime.
     * @param prev	Boundary date. Must have a time zone (any time zone) iff the period reference date has one.
     * @param count	Number of periods to add. Optional. Must be an integer number, may be positive or negative, default 1
     * @return (prev + count * period), in the same timezone as prev.
     * @throws timezonecomplete.Argument.Prev if prev is undefined
     * @throws timezonecomplete.Argument.Count if count is not an integer number
     */
    findNext(prev: DateTime, count?: number): DateTime;
    /**
     * The last occurrence of the period less than
     * the given date. The given date need not be at a period boundary.
     * Pre: the fromdate and the period reference date must either both have timezones or not
     * @param fromDate: the date before which to return the next date
     * @return the last date matching the period before fromDate, given
     *         in the same zone as the fromDate.
     * @throws timezonecomplete.UnawareToAwareConversion if not both `from` and the reference date are both aware or unaware of time zone
     * @throws timezonecomplete.NotFound.Zone if the UTC time zone doesn't exist in the time zone database
     */
    findLast(from: DateTime): DateTime;
    /**
     * Returns the previous timestamp in the period. The given timestamp must
     * be at a period boundary, otherwise the answer is incorrect.
     * @param prev	Boundary date. Must have a time zone (any time zone) iff the period reference date has one.
     * @param count	Number of periods to subtract. Optional. Must be an integer number, may be negative.
     * @return (next - count * period), in the same timezone as next.
     * @throws timezonecomplete.Argument.Next if prev is undefined
     * @throws timezonecomplete.Argument.Count if count is not an integer number
     */
    findPrev(next: DateTime, count?: number): DateTime;
    /**
     * Checks whether the given date is on a period boundary
     * (expensive!)
     * @throws timezonecomplete.UnawareToAwareConversion if not both `occurrence` and the reference date are both aware or unaware of time zone
     * @throws timezonecomplete.NotFound.Zone if the UTC time zone doesn't exist in the time zone database
     */
    isBoundary(occurrence: DateTime): boolean;
    /**
     * Returns true iff this period has the same effect as the given one.
     * i.e. a period of 24 hours is equal to one of 1 day if they have the same UTC reference moment
     * and same dst.
     * @throws timezonecomplete.UnawareToAwareConversion if not both `other#reference()` and the reference date are both aware or unaware
     * of time zone
     * @throws timezonecomplete.NotFound.Zone if the UTC time zone doesn't exist in the time zone database
     */
    equals(other: Period): boolean;
    /**
     * Returns true iff this period was constructed with identical arguments to the other one.
     * @throws nothing
     */
    identical(other: Period): boolean;
    /**
     * Returns an ISO duration string e.g.
     * 2014-01-01T12:00:00.000+01:00/P1H
     * 2014-01-01T12:00:00.000+01:00/PT1M   (one minute)
     * 2014-01-01T12:00:00.000+01:00/P1M   (one month)
     * @throws nothing
     */
    toIsoString(): string;
    /**
     * A string representation e.g.
     * "10 years, referenceing at 2014-03-01T12:00:00 Europe/Amsterdam, keeping regular intervals".
     * @throws nothing
     */
    toString(): string;
    /**
     * Returns a JSON-compatible representation of this period
     * @throws nothing
     */
    toJson(): PeriodJson;
    /**
     * Corrects the difference between _reference and _intReference.
     * @throws nothing
     */
    private _correctDay;
    /**
     * If this._internalUnit in [Month, Year], normalizes the day-of-month
     * to <= 28.
     * @return a new date if different, otherwise the exact same object (no clone!)
     * @throws nothing
     */
    private _normalizeDay;
    /**
     * Returns true if DST handling is relevant for us.
     * (i.e. if the reference time zone has DST)
     * @throws nothing
     */
    private _dstRelevant;
    /**
     * Normalize the values where possible - not all values
     * are convertible into one another. Weeks are converted to days.
     * E.g. more than 60 minutes is transferred to hours,
     * but seconds cannot be transferred to minutes due to leap seconds.
     * Weeks are converted back to days.
     * @throws nothing
     */
    private _calcInternalValues;
}
/**
 * PeriodDst encoded a a string
 */
export type PeriodDstJson = "regular" | "local";
/**
 * Period encoded as a JSON object
 */
export interface PeriodJson {
    /**
     * Reference date as iso timestamp + time zone
     */
    reference: string;
    /**
     * Interval as a timezonecomplete duration string
     */
    duration: string;
    /**
     * Daylight saving time handling
     */
    periodDst: PeriodDstJson;
}
/**
 * Returns true iff the given json value represents a valid period JSON
 * @param json
 * @throws nothing
 */
export declare function isValidPeriodJson(json: PeriodJson): boolean;
/**
 * Checks if a given object is of type Period. Note that it does not work for sub classes. However, use this to be robust
 * against different versions of the library in one process instead of instanceof
 * @param value Value to check
 * @throws nothing
 */
export declare function isPeriod(value: any): value is Period;
/**
 * Options for timestampOnWeekTimeGreaterThanOrEqualTo() and timestampOnWeekTimeLessThan()
 */
export interface WeekTimeOpts {
    /**
     * Timestamp to use as a basis
     */
    reference: DateTime;
    /**
     * Desired day of week
     */
    weekday: basics.WeekDay;
    /**
     * Desired time (hours 0-23)
     */
    hour: number;
    /**
     * Desired time (minutes 0-59)
     */
    minute?: number;
    /**
     * Desired time (seconds 0-59)
     */
    second?: number;
    /**
     * Desired time (milliseconds 0-999)
     */
    millisecond?: number;
}
/**
 * Returns the first timestamp >= `opts.reference` that matches the given weekday and time. Uses the time zone and DST settings
 * of the given reference time.
 * @param opts
 * @throws timezonecomplete.Argument.Hour if opts.hour out of range
 * @throws timezonecomplete.Argument.Minute if opts.minute out of range
 * @throws timezonecomplete.Argument.Second if opts.second out of range
 * @throws timezonecomplete.Argument.Millisecond if opts.millisecond out of range
 * @throws timezonecomplete.Argument.Weekday if opts.weekday out of range
 */
export declare function timestampOnWeekTimeGreaterThanOrEqualTo(opts: WeekTimeOpts): DateTime;
/**
 * Returns the first timestamp < `opts.reference` that matches the given weekday and time. Uses the time zone and DST settings
 * of the given reference time.
 * @param opts
 * @throws timezonecomplete.Argument.Hour if opts.hour out of range
 * @throws timezonecomplete.Argument.Minute if opts.minute out of range
 * @throws timezonecomplete.Argument.Second if opts.second out of range
 * @throws timezonecomplete.Argument.Millisecond if opts.millisecond out of range
 * @throws timezonecomplete.Argument.Weekday if opts.weekday out of range
 */
export declare function timestampOnWeekTimeLessThan(opts: WeekTimeOpts): DateTime;
