在Xamarin.Forms中转换Google Calendar API v3事件DateTime格式并展示
Got it, let's walk through how to fix this step by step. The core tasks are properly parsing the date/time values from Google Calendar API, formatting them into your desired "Fri May 25, 2018 12:00 PM" style, and handling both timed and all-day events correctly (since Google treats these two event types differently).
Step 1: Update the GetSchoolEvents Method
First, we'll replace your current date-handling logic with code that parses and formats dates properly. We'll also add support for event locations (since your desired layout includes it) and fix a quirk with all-day event end dates—Google sets the end date to the day after the event actually ends.
Make sure to add using System.Globalization; at the top of your ViewModel file to access consistent formatting cultures.
Here's the updated method:
using System.Globalization; // ... rest of your namespace/class code public List<SchoolEvent> GetSchoolEvents() { var service = new CalendarService(new BaseClientService.Initializer() { ApiKey = "Key", ApplicationName = "TFA Calendar Mobile App", }); EventsResource.ListRequest request = service.Events.List(SelectedCalendar.SchoolCalId); request.TimeMin = DateTime.Now; request.ShowDeleted = false; request.SingleEvents = true; request.MaxResults = 10; request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime; Events events = request.Execute(); List<SchoolEvent> schoolEvents = new List<SchoolEvent>(); if (events.Items != null && events.Items.Count > 0) { foreach (var eventItem in events.Items) { // Handle Start Time/Date string formattedStart; if (eventItem.Start.DateTime.HasValue) { // Timed event: format with date and time formattedStart = eventItem.Start.DateTime.Value.ToString( "ddd MMM d, yyyy h:mm tt", CultureInfo.InvariantCulture); } else { // All-day event: parse the date string and format if (DateTime.TryParse(eventItem.Start.Date, out DateTime startDate)) { formattedStart = startDate.ToString( "ddd MMM d, yyyy", CultureInfo.InvariantCulture); } else { formattedStart = "Unknown Start Date"; } } // Handle End Time/Date (fix Google's all-day end date quirk) string formattedEnd; if (eventItem.End.DateTime.HasValue) { // Timed event: format with date and time formattedEnd = eventItem.End.DateTime.Value.ToString( "ddd MMM d, yyyy h:mm tt", CultureInfo.InvariantCulture); } else { // All-day event: Google uses the next day as end date, so subtract 1 day if (DateTime.TryParse(eventItem.End.Date, out DateTime endDate)) { formattedEnd = endDate.AddDays(-1).ToString( "ddd MMM d, yyyy", CultureInfo.InvariantCulture); } else { formattedEnd = "Unknown End Date"; } } // Add the event with all required fields schoolEvents.Add(new SchoolEvent() { EventTitle = eventItem.Summary, EventDescription = eventItem.Description, EventLocation = eventItem.Location, // Add location for your layout EventStartTime = formattedStart, EventEndTime = formattedEnd }); } } return schoolEvents; }
Step 2: Ensure Your SchoolEvent Class Includes the EventLocation Property
Make sure your model class has the location field to match the code above:
public class SchoolEvent { public string EventTitle { get; set; } public string EventDescription { get; set; } public string EventLocation { get; set; } // Add this if missing public string EventStartTime { get; set; } public string EventEndTime { get; set; } }
Step 3: Configure the Xamarin.Forms ListView ItemTemplate
Set up your ListView in XAML to display the formatted data exactly as you specified:
<ListView ItemsSource="{Binding SchoolEvents}" HasUnevenRows="True"> <!-- Use this to accommodate variable content length --> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout Padding="12" Spacing="4"> <!-- Event Name --> <Label Text="{Binding EventTitle}" FontSize="Headline" FontAttributes="Bold"/> <!-- Event Location --> <Label Text="{Binding EventLocation}" FontSize="Subtitle" TextColor="Gray"/> <!-- Start Time --> <Label Text="{Binding StringFormat='Starts: {0}', Path=EventStartTime}" FontSize="Body"/> <!-- End Time --> <Label Text="{Binding StringFormat='Ends: {0}', Path=EventEndTime}" FontSize="Body"/> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>
Key Details to Note:
CultureInfo.InvariantCulture: Ensures the date format stays consistent (e.g., "May" instead of localized month names) across iOS and Android, regardless of the user's region settings.- All-day Event Fix: Google Calendar marks all-day events with an end date that's one day after the actual event ends. We subtract one day to display the correct end date.
- Error Handling: Added fallbacks like "Unknown Date" to make your app more robust if date parsing fails for any reason.
内容的提问来源于stack exchange,提问作者Michael Maxime

