parseICS static method

Map<String, Map<String, dynamic>> parseICS(
  1. String icsContent,
  2. String timeZone
)

Implementation

static Map<String, Map<String, dynamic>> parseICS(
  String icsContent,
  String timeZone,
) {
  // Split ICS content into lines
  final lines = LineSplitter.split(icsContent);

  // Parse events
  // final List<Map<String, String>> events = [];
  Map<String, String>? currentEvent;
  Map<String, Map<String, dynamic>> blockedDates = {};

  late DateTimeRange blockedDuration;
  String? day;
  late DateTime startTime;
  late DateTime endTime;

  for (final line in lines) {
    if (line.startsWith('BEGIN:VEVENT')) {
      currentEvent = {};
      // blockedDuration = TimeRange(from: "", to: "");
    } else if (line.startsWith('END:VEVENT')) {
      if (currentEvent != null) {
        // events.add(Map.from(currentEvent));
        currentEvent = null;
        blockedDates[day]!['timings'].add(blockedDuration);
        blockedDates[day]!['fullDayOut'] = false;
      }
    } else if (currentEvent != null) {
      final parts = line.split(':');
      if (parts.length == 2) {
        currentEvent[parts[0]] = parts[1];
        if (parts[0].contains("DTSTART")) {
          // print("start here DTSTART ->  ${parts[0]} : ${parts[1]}");

          startTime = DateTime.parse(parts[1]);

          RegExp regex = RegExp(r"DTSTART;TZID=(.*)");

          Match? match = regex.firstMatch(parts[0]);

          if (match != null) {
            String result = match.group(1) ?? "";
            if (result.isNotEmpty && result != timeZone) {
              startTime = getConvertedTime(startTime.toLocal(), timeZone);
            } else {
              startTime = startTime.toLocal();
            }
          } else {
            startTime = startTime.toLocal();
          }

          day = DateFormat('yMd').format(startTime);
          if (!blockedDates.containsKey(day)) {
            blockedDates[day] = {
              "timings": [],
              "weekday": DateFormat('EEEE').format(startTime),
            };
          }

          blockedDuration = DateTimeRange(start: startTime, end: startTime);
        } else if (parts[0].contains("DTEND")) {
          endTime = DateTime.parse(parts[1]);

          RegExp regex = RegExp(r"DTEND;TZID=(.*)");

          Match? match = regex.firstMatch(parts[0]);

          if (match != null) {
            String result = match.group(1) ?? "";
            if (result.isNotEmpty && result != timeZone) {
              endTime = getConvertedTime(endTime.toLocal(), timeZone);
            } else {
              endTime = endTime.toLocal();
            }
          } else {
            endTime = endTime.toLocal();
          }

          int difference = endTime.difference(startTime).inDays;
          if (difference > 0) {
            blockedDuration = DateTimeRange(
              start: blockedDuration.start,
              end: DateTime(
                blockedDuration.start.year,
                blockedDuration.start.month,
                blockedDuration.start.day,
                23,
                59,
                59,
              ),
            );
            blockedDates[day]!['timings'].add(blockedDuration);
            blockedDates[day]!['fullDayOut'] = false;
            while (difference > 1) {
              // blockedDuration = TimeRange(from: "", to: "");
              startTime = startTime.add(const Duration(days: 1));
              day = DateFormat('yMd').format(startTime);
              if (!blockedDates.containsKey(day)) {
                blockedDates[day] = {
                  "timings": [],
                  "weekday": DateFormat('EEEE').format(startTime),
                  "fullDayOut": true,
                };
              }

              blockedDuration = DateTimeRange(
                start: DateTime(
                  startTime.year,
                  startTime.month,
                  startTime.day,
                  0,
                  0,
                  0,
                ),
                end: DateTime(
                  startTime.year,
                  startTime.month,
                  startTime.day,
                  23,
                  59,
                  59,
                ),
              );
              blockedDates[day]!['timings'].add(blockedDuration);
              difference--;
            }

            day = DateFormat('yMd').format(endTime);
            if (!blockedDates.containsKey(day)) {
              blockedDates[day] = {
                "timings": [],
                "weekday": DateFormat('EEEE').format(endTime),
              };
            }

            blockedDuration = DateTimeRange(
              start: DateTime(
                endTime.year,
                endTime.month,
                endTime.day,
                0,
                0,
                0,
              ),
              end: endTime,
            );
          } else {
            blockedDuration = DateTimeRange(start: startTime, end: endTime);
          }
        }
      }
    }
  }

  return blockedDates;
}