Jak dodać wydarzenie do kalendarza z poprawną strefą czasową?

0

Cześć.
Mam problem z kalendarzem, tworzę projekt w ASP.NET MVC C#.

Problem jest taki, że kiedy dodaje nowy Event do Kalendarza automatycznie dodaje się do dnia dzisiejszego tj. 08.01.2024 i wpisuje datę np. 1:07 PM mimo, że u mnie jest 14;10. Myślę, że chodzi o TimeZone ale czego bym nie próbował to w końcu po dodaniu eventu kalendarz go nie wyświetla. Może ktoś robił już coś podobnego i ma pomysł co mógłbym zmienić?

Utworzyłem model bazy danych dla Eventów.

screenshot-20240108140852.png
Następnie kontroler:

namespace Narzedzia.Controllers
{
    public class CalendarController : Controller
    {
        private readonly ApplicationDbContext _context;

        public CalendarController(ApplicationDbContext context)
        {
            _context = context;
        }
        public IActionResult CalendarView()
        {
            return View();
        }
        public JsonResult GetEvents()
        {
            var eventsFromDatabase = _context.Calendars.ToList();

            var events = eventsFromDatabase.Select(e => new
            {
                title = e.SubjectCal,
                description = e.DescriptionCal,
                StartCal = e.StartCal.ToString("yyyy-MM-ddTHH:mm:ss"),
                EndCal = e.EndCal != null ? e.EndCal.ToString("yyyy-MM-ddTHH:mm:ss") : null,
                color = e.ThemeColor
            }).ToList();

            return Json(events);
        }



        public IActionResult AddEvent()
        {
            return View();
        }

        [HttpPost]
        public IActionResult AddEvent(Calendar calendarEvent)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    // Utwórz nowy obiekt kalendarza w kontekście bazy danych
                    _context.Calendars.Add(calendarEvent);

                    // Zapisz zmiany w bazie danych
                    _context.SaveChanges();

                    return RedirectToAction("CalendarView");
                }
                catch (Exception ex)
                {
                    // Obsłuż ewentualny błąd
                    ModelState.AddModelError(string.Empty, $"Wystąpił błąd podczas zapisywania wydarzenia: {ex.Message}");
                }
            }

            // Jeśli ModelState.IsValid nie jest spełnione, wróć do widoku z błędami walidacji
            return View(calendarEvent);
        }
    }
}

Oraz zrobiłem dwa widoki.

@{
    ViewBag.Title = "Calendar";
}

<h2>Calendar</h2>
<div id="calendar"></div>
<button id="addEventButton" class="btn btn-success">Dodaj nowe wydarzenie</button>

<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.print.css" rel="stylesheet" media="print" />
@section Scripts{
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.33/moment-timezone-with-data.min.js"></script>


    <script>
        $(document).ready(function () {
            var events = [];
            $.ajax({
                type: "GET",
                url: "/Calendar/GetEvents",
                success: function (data) {
                    $.each(data, function (i, v) {
                        events.push({
                            title: v.title,
                            description: v.description,
                             start: moment(v.StartCal).tz('Europe/Warsaw'),
                    end: v.EndCal != null ? moment(v.EndCal).tz('Europe/Warsaw') : null,
                            color: v.color
                        });
                    })

                    GenerateCalender(events);
                },
                error: function (error) {
                    alert('failed');
                }
            })

            $('#addEventButton').on('click', function () {
                window.location.href = '/Calendar/AddEvent';
            });


            function GenerateCalender(events) {
                // Usuń tę linię
                // $('#calendar').fullCalendar('destroy');

                $('#calendar').fullCalendar({
                    editable: true,
                    selectable: true,
                    contentHeight: 400,
                    defaultDate: new Date(),
                    timeFormat: 'h(:mm)a',
                    columnFormat: 'dddd', // full weekday names like Monday,Tuesday
                    header: {
                        left: 'prev,next today',
                        center: 'title',
                        right: 'month,basicWeek,basicDay,agenda'
                    },
                    eventLimit: true,
                    eventColor: '#378006',
                    events: events.map(function (event) {
                        return {
                            title: event.title,
                            description: event.description,
                            start: moment.utc(event.start),
                            end: event.end != null ? moment.utc(event.end) : null,
                            color: event.color
                        };
                    })
                });
            }
        })
    </script>
}

Oraz drugi widok do dodawania Eventów.

screenshot-20240108141102.png

I po dodaniu eventu wyglada to tak:

screenshot-20240108141122.png

0

może trochę nie na temat ale namespace Narzedzia.Controllers wygląda źle, może warto byłoby zmienić nazwę komponentu na Tools zgodnie z konwencją? taka luźna sugestia :)

1

moment, jQuery, ASP MVC... niezły zabytek.
Nie czytałem prawie nic z posta ale w razie czego do przechowywania daty ze strefą czasową służy DateTimeOffset

0

Na oko, to do tablicy events (w tym kodzie JS) ładujesz eventy z datami w polskiej strefie czasowej, natomiast przy generowaniu kalendarza konwertujesz daty do UTC. Stąd masz różnice pomiędzy tym co w bazie, a tym co się wyświetla na froncie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1