Parse DURATION property from iCal
This commit is contained in:
parent
5f452c026e
commit
4f02fb27da
3 changed files with 61 additions and 5 deletions
|
@ -16,6 +16,17 @@ namespace BlazorApp.Data
|
||||||
public DateTime? DtStart { get; set; }
|
public DateTime? DtStart { get; set; }
|
||||||
public DateTime? DtEnd { get; set; }
|
public DateTime? DtEnd { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
public TimeSpan? Duration { get; set; }
|
||||||
|
|
||||||
|
public DateTime? CalculatedEnd
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Duration != null)
|
||||||
|
return DtStart + Duration;
|
||||||
|
return DtEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Calendar
|
public class Calendar
|
||||||
|
@ -40,6 +51,48 @@ namespace BlazorApp.Data
|
||||||
return DateTime.ParseExact(s, format, CultureInfo.InvariantCulture);
|
return DateTime.ParseExact(s, format, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Very non-strict parser of durations as specified in
|
||||||
|
/// https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.6
|
||||||
|
/// </summary>
|
||||||
|
private static TimeSpan? _parseDuration(string s)
|
||||||
|
{
|
||||||
|
var timeSpan = new TimeSpan();
|
||||||
|
var positive = s[0] != '-';
|
||||||
|
var value = 0;
|
||||||
|
foreach (var c in s)
|
||||||
|
{
|
||||||
|
if (char.IsDigit(c))
|
||||||
|
{
|
||||||
|
value = value * 10 + (c - '0');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'W':
|
||||||
|
timeSpan += TimeSpan.FromDays(value * 7);
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
timeSpan += TimeSpan.FromDays(value);
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
timeSpan += TimeSpan.FromHours(value);
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
timeSpan += TimeSpan.FromMinutes(value);
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
timeSpan += TimeSpan.FromSeconds(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return positive ? timeSpan : -timeSpan;
|
||||||
|
}
|
||||||
|
|
||||||
private static List<Event> ParseICal(string iCal)
|
private static List<Event> ParseICal(string iCal)
|
||||||
{
|
{
|
||||||
Event @event = null;
|
Event @event = null;
|
||||||
|
@ -108,6 +161,9 @@ namespace BlazorApp.Data
|
||||||
case "DTEND":
|
case "DTEND":
|
||||||
@event.DtEnd = _parseDateTime(value);
|
@event.DtEnd = _parseDateTime(value);
|
||||||
break;
|
break;
|
||||||
|
case "DURATION":
|
||||||
|
@event.Duration = _parseDuration(value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +178,7 @@ namespace BlazorApp.Data
|
||||||
var client = new HttpClient();
|
var client = new HttpClient();
|
||||||
if (AuthorizationHeader != null)
|
if (AuthorizationHeader != null)
|
||||||
client.DefaultRequestHeaders.Add("Authorization", AuthorizationHeader);
|
client.DefaultRequestHeaders.Add("Authorization", AuthorizationHeader);
|
||||||
|
|
||||||
var body = await client.GetStringAsync(Url);
|
var body = await client.GetStringAsync(Url);
|
||||||
var events = ParseICal(body);
|
var events = ParseICal(body);
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,10 @@ else
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (@event.DtEnd != null)
|
@if (@event.CalculatedEnd != null)
|
||||||
{
|
{
|
||||||
<div>
|
<div>
|
||||||
<strong>End:</strong> @(@event.DtEnd)
|
<strong>End:</strong> @(@event.CalculatedEnd)
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,10 @@ else
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (_event.DtEnd != null)
|
@if (_event.CalculatedEnd != null)
|
||||||
{
|
{
|
||||||
<div>
|
<div>
|
||||||
<strong>End:</strong> @_event.DtEnd
|
<strong>End:</strong> @_event.CalculatedEnd
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue