Example #1
0
        public FormattedString FormatRange(EcmaValue startDate, EcmaValue endDate, out string[] annotations)
        {
            EnsureInitialized();
            if (startDate == default || endDate == default)
            {
                throw new EcmaTypeErrorException("Invalid time value");
            }
            EcmaValue x = startDate.ToNumber();
            EcmaValue y = endDate.ToNumber();

            if (x > y)
            {
                throw new EcmaRangeErrorException("Invalid time value");
            }
            if (x < MinTime || x > MaxTime)
            {
                throw new EcmaRangeErrorException("Invalid time value");
            }
            if (y < MinTime || y > MaxTime)
            {
                throw new EcmaRangeErrorException("Invalid time value");
            }
            TimeZoneInfo    timezone = TZConvert.GetTimeZoneInfo(this.TimeZone);
            DateTime        dt1      = unixEpochUtc.AddMilliseconds(x.ToInt64() + timezone.BaseUtcOffset.TotalMilliseconds);
            DateTime        dt2      = unixEpochUtc.AddMilliseconds(y.ToInt64() + timezone.BaseUtcOffset.TotalMilliseconds);
            bool            dateFieldsPracticallyEqual     = true;
            bool            patternContainsLargerDateField = false;
            FormattedString pattern = null;

            foreach (FormattedPartType part in new[] { FormattedPartType.Era, FormattedPartType.Year, FormattedPartType.Month, FormattedPartType.Day, FormattedPartType.DayPeriod, FormattedPartType.Hour, FormattedPartType.Minute, FormattedPartType.Second })
            {
                int v1 = GetPartValue(part, dt1);
                int v2 = GetPartValue(part, dt2);
                if (v1 != v2)
                {
                    dateFieldsPracticallyEqual = false;
                }
                FormattedString rp = format.GetRangePattern(part);
                if (pattern != null && rp == null)
                {
                    patternContainsLargerDateField = true;
                }
                pattern = rp ?? pattern;
                if (!dateFieldsPracticallyEqual || patternContainsLargerDateField)
                {
                    break;
                }
            }
            if (dateFieldsPracticallyEqual)
            {
                FormattedString str = FormatDateTime(dt1, format.Pattern);
                annotations = Enumerable.Range(0, str.PartCount).Select(v => "shared").ToArray();
                return(str);
            }
            if (pattern == null)
            {
                pattern = format.GetDefaultRangePattern();
            }
            List <FormattedPart> parts   = new List <FormattedPart>(pattern);
            List <string>        sources = new List <string>();

            for (int i = parts.Count - 1; i >= 0; i--)
            {
                FormattedString placeable = null;
                string          source    = null;
                switch (parts[i].Type)
                {
                case FormattedPartType.SharedPlaceholder:
                    placeable = FormatDateTime(dt1, parts[i].Value);
                    source    = "shared";
                    break;

                case FormattedPartType.StartRangePlaceholder:
                    placeable = FormatDateTime(dt1, parts[i].Value);
                    source    = "startRange";
                    break;

                case FormattedPartType.EndRangePlaceholder:
                    placeable = FormatDateTime(dt2, parts[i].Value);
                    source    = "endRange";
                    break;

                case FormattedPartType.Placeholder:
                    bool isStartRange = parts[i].Value == "{0}";
                    placeable = FormatDateTime(isStartRange ? dt1 : dt2, format.Pattern);
                    source    = isStartRange ? "startRange" : "endRange";
                    break;

                default:
                    sources.Insert(0, "shared");
                    break;
                }
                if (placeable != null)
                {
                    parts.RemoveAt(i);
                    parts.InsertRange(i, placeable);
                    sources.InsertRange(0, Enumerable.Range(0, placeable.PartCount).Select(_ => source));
                }
            }
            annotations = sources.ToArray();
            return(new FormattedString(parts));
        }