#undef PTIME_ANY_BORDER
#undef PTIME_ANY_INNER
#ifdef PTIME_AMBIGUOUS_LATER
#  define PTIME_ANY_BORDER local_lower
#  define PTIME_ANY_INNER  (inner_epoch >= outborder && outer_epoch < inborder)
#else
#  define PTIME_ANY_BORDER local_upper
#  define PTIME_ANY_INNER  (min_epoch >= outborder && min_epoch < inborder)
#endif

#undef PTIME_ANY_NORMALIZE_LEAPSEC
#ifdef PTIME_ANY_NORMALIZE
#  define PTIME_ANY_NORMALIZE_LEAPSEC(trans) \
    igmtime(local_epoch, date); \
    date->n_zone = trans.n_abbrev; \
    date->gmtoff = trans.gmt_offset; \
    date->isdst  = trans.isdst; \
    if (keep_input_sec) date->sec = input_sec;
#else
#  define PTIME_ANY_NORMALIZE_LEAPSEC(trans)
#endif

#undef PTIME_ANY_LEAPSEC_CORR
#define PTIME_ANY_LEAPSEC_CORR(trans) \
    if (local_epoch < trans.leap_lend) { \
        ptime_t norm_sec = (date->sec + OUTLIM_EPOCH_BY_86400) % 60; \
        bool keep_input_sec = false; \
        int32_t offset = trans.offset; \
        if (input_sec >= 60 && input_sec < 60 + trans.leap_delta) { \
            local_epoch -= trans.leap_delta; \
            keep_input_sec = true; \
        } \
        else if (norm_sec >= 60 - trans.leap_delta) offset += trans.leap_delta; \
        PTIME_ANY_NORMALIZE_LEAPSEC(trans); \
        return local_epoch - offset; \
    }
    
    
{
    ptime_t input_sec = date->sec;
    
    ptime_t local_epoch = itimegml(date);
    
    if (local_epoch < zone->ltrans.PTIME_ANY_BORDER) {
        __PTIME_TRANS_BINFIND(local_epoch, PTIME_ANY_BORDER);
        PTIME_ANY_LEAPSEC_CORR(zone->trans[index]);
#ifdef PTIME_ANY_NORMALIZE
        if (local_epoch >= zone->trans[index].local_end) {
            // normalize forward jump period
            igmtime(local_epoch + zone->trans[index+1].delta, date);
            date->n_zone = zone->trans[index+1].n_abbrev;
            date->gmtoff = zone->trans[index+1].gmt_offset;
            date->isdst  = zone->trans[index+1].isdst;
        }
        else {
            igmtime(local_epoch, date);
            date->n_zone = zone->trans[index].n_abbrev;
            date->gmtoff = zone->trans[index].gmt_offset;
            date->isdst  = zone->trans[index].isdst;
        }
#endif
        return local_epoch - zone->trans[index].offset;
    }
    
    PTIME_ANY_LEAPSEC_CORR(zone->ltrans);
    
    if (!zone->future.hasdst) {
#ifdef PTIME_ANY_NORMALIZE
        igmtime(local_epoch, date);
        date->n_zone = zone->future.outer.n_abbrev;
        date->gmtoff = zone->future.outer.gmt_offset;
        date->isdst  = zone->future.outer.isdst;
#endif
        return local_epoch - zone->future.outer.offset;
    }

    igmtime(local_epoch, date); // need yday and wday
    int is_leap = is_leap_year(date->year);
    ptime_t outborder   = _calc_rule_epoch(is_leap, date, zone->future.outer.end) - zone->future.outer.offset;
    ptime_t inborder    = _calc_rule_epoch(is_leap, date, zone->future.inner.end) - zone->future.inner.offset;
    ptime_t min_epoch   = local_epoch - zone->future.max_offset;
    ptime_t outer_epoch = local_epoch - zone->future.outer.offset;
    ptime_t inner_epoch = local_epoch - zone->future.inner.offset;

#ifndef PTIME_ANY_NORMALIZE
    return PTIME_ANY_INNER ? inner_epoch : outer_epoch;
#else
    if (PTIME_ANY_INNER) {
        if (zone->future.delta < 0 && inner_epoch >= inborder) {
            // normalize forward jump period for southern hemisphere
            igmtime(local_epoch - zone->future.delta, date);
            date->n_zone = zone->future.outer.n_abbrev;
            date->gmtoff = zone->future.outer.gmt_offset;
            date->isdst  = zone->future.outer.isdst;
        } else {
            date->n_zone = zone->future.inner.n_abbrev;
            date->gmtoff = zone->future.inner.gmt_offset;
            date->isdst  = zone->future.inner.isdst;
        }
        return inner_epoch;
    }
    else if (zone->future.delta > 0 && inner_epoch < outborder && outer_epoch >= outborder) {
        // normalize forward jump period for northern hemisphere
        igmtime(local_epoch + zone->future.delta, date);
        date->n_zone = zone->future.inner.n_abbrev;
        date->gmtoff = zone->future.inner.gmt_offset;
        date->isdst  = zone->future.inner.isdst;
    } else {
        date->n_zone = zone->future.outer.n_abbrev;
        date->gmtoff = zone->future.outer.gmt_offset;
        date->isdst  = zone->future.outer.isdst;
    }
    return outer_epoch;
#endif
}
