diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
index d203ad680dcae02fda4fc736e2099845c8f5ce3b..3263225dc890242ed038f8b5f58153278e5aea64 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
@@ -93,6 +93,7 @@ import SecondaryActionButton from "aleksis.core/components/generic/buttons/Secon
 import loadingMixin from "aleksis.core/mixins/loadingMixin.js";
 import permissionsMixin from "aleksis.core/mixins/permissions.js";
 import mutateMixin from "aleksis.core/mixins/mutateMixin.js";
+import { DateTime } from "luxon";
 
 import { createAbsencesForPersons } from "./absenceCreation.graphql";
 
@@ -122,6 +123,7 @@ export default {
   },
   mounted() {
     this.addPermissions(["alsijil.view_register_absence_rule"]);
+    this.clearForm();
   },
   methods: {
     cancel() {
@@ -131,8 +133,12 @@ export default {
     },
     clearForm() {
       this.persons = [];
-      this.startDate = "";
-      this.endDate = "";
+      this.startDate = DateTime.now()
+        .startOf("day")
+        .toISO({ suppressSeconds: true });
+      this.endDate = DateTime.now()
+        .endOf("day")
+        .toISO({ suppressSeconds: true });
       this.comment = "";
       this.absenceReason = "";
     },
@@ -142,8 +148,8 @@ export default {
         createAbsencesForPersons,
         {
           persons: this.persons.map((p) => p.id),
-          start: this.startDate,
-          end: this.endDate,
+          start: this.$toUTCISO(this.$parseISODate(this.startDate)),
+          end: this.$toUTCISO(this.$parseISODate(this.endDate)),
           comment: this.comment,
           reason: this.absenceReason,
         },
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
index 559824bdf4cb8bb214d1be3acebba38c08c836cd..239c83d6bbd48700773c024967636a82f3d3c4a8 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
@@ -26,9 +26,10 @@
       <v-row>
         <v-col cols="12" :sm="6" class="pl-0">
           <div aria-required="true">
-            <date-field
+            <date-time-field
               :label="$t('forms.labels.start')"
-              :max="endDate"
+              :max-date="endDate"
+              :max-time="maxStartTime"
               :rules="$rules().required.build()"
               :value="startDate"
               @input="$emit('start-date', $event)"
@@ -37,9 +38,10 @@
         </v-col>
         <v-col cols="12" :sm="6" class="pr-0">
           <div aria-required="true">
-            <date-field
+            <date-time-field
               :label="$t('forms.labels.end')"
-              :min="startDate"
+              :min-date="startDate"
+              :min-time="minEndTime"
               :rules="$rules().required.build()"
               :value="endDate"
               @input="$emit('end-date', $event)"
@@ -69,15 +71,16 @@
 
 <script>
 import AbsenceReasonGroupSelect from "aleksis.apps.kolego/components/AbsenceReasonGroupSelect.vue";
-import DateField from "aleksis.core/components/generic/forms/DateField.vue";
+import DateTimeField from "aleksis.core/components/generic/forms/DateTimeField.vue";
 import { persons } from "./absenceCreation.graphql";
 import formRulesMixin from "aleksis.core/mixins/formRulesMixin.js";
+import { DateTime } from "luxon";
 
 export default {
   name: "AbsenceCreationForm",
   components: {
     AbsenceReasonGroupSelect,
-    DateField,
+    DateTimeField,
   },
   mixins: [formRulesMixin],
   emits: [
@@ -113,5 +116,25 @@ export default {
       required: true,
     },
   },
+  computed: {
+    maxStartTime() {
+      // Only if on the same day
+      const start = DateTime.fromISO(this.startDate);
+      const end = DateTime.fromISO(this.endDate);
+
+      if (start.day !== end.day) return;
+
+      return end.minus({ minutes: 5 }).toFormat("HH:mm");
+    },
+    minEndTime() {
+      // Only if on the same day
+      const start = DateTime.fromISO(this.startDate);
+      const end = DateTime.fromISO(this.endDate);
+
+      if (start.day !== end.day) return;
+
+      return start.plus({ minutes: 5 }).toFormat("HH:mm");
+    },
+  },
 };
 </script>
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql
index 21ce30d0b871bcfbd9a5b40b671a8594948a2569..5a520453f35062d49edd5eb82aca291384e2f739 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql
@@ -6,7 +6,7 @@ query persons {
   }
 }
 
-query lessonsForPersons($persons: [ID]!, $start: Date!, $end: Date!) {
+query lessonsForPersons($persons: [ID]!, $start: DateTime!, $end: DateTime!) {
   items: lessonsForPersons(persons: $persons, start: $start, end: $end) {
     id
     lessons {
@@ -31,8 +31,8 @@ query lessonsForPersons($persons: [ID]!, $start: Date!, $end: Date!) {
 # Use absencesInputType?
 mutation createAbsencesForPersons(
   $persons: [ID]!
-  $start: Date!
-  $end: Date!
+  $start: DateTime!
+  $end: DateTime!
   $comment: String
   $reason: ID!
 ) {
diff --git a/aleksis/apps/alsijil/managers.py b/aleksis/apps/alsijil/managers.py
index 7d0130805275359672d1337133eacd1b0a2b62ad..dc29fae25c189c7c2250279a6e8d86206f52e520 100644
--- a/aleksis/apps/alsijil/managers.py
+++ b/aleksis/apps/alsijil/managers.py
@@ -11,7 +11,7 @@ from django.utils.translation import gettext as _
 from calendarweek import CalendarWeek
 
 from aleksis.apps.chronos.managers import DateRangeQuerySetMixin
-from aleksis.core.managers import AlekSISBaseManagerWithoutMigrations, PolymorphicBaseManager
+from aleksis.core.managers import AlekSISBaseManagerWithoutMigrations, RecurrencePolymorphicManager
 
 if TYPE_CHECKING:
     from aleksis.core.models import Group
@@ -189,7 +189,7 @@ class GroupRoleAssignmentQuerySet(DateRangeQuerySetMixin, QuerySet):
         return self.filter(Q(groups=group) | Q(groups__child_groups=group))
 
 
-class DocumentationManager(PolymorphicBaseManager):
+class DocumentationManager(RecurrencePolymorphicManager):
     """Manager adding specific methods to documentations."""
 
     def get_queryset(self):
@@ -205,9 +205,7 @@ class DocumentationManager(PolymorphicBaseManager):
         )
 
 
-class ParticipationStatusManager(PolymorphicBaseManager):
+class ParticipationStatusManager(RecurrencePolymorphicManager):
     """Manager adding specific methods to participation statuses."""
 
-    def get_queryset(self):
-        """Ensure often used related data are loaded as well."""
-        return super().get_queryset().select_related("person", "absence_reason", "base_absence")
+    pass
diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py
index f63b8c2c9b8c5c029371e4663f6d70b2e5271bb8..ab87c4306cd144d4c5f27c00914aceeb865584a7 100644
--- a/aleksis/apps/alsijil/schema/__init__.py
+++ b/aleksis/apps/alsijil/schema/__init__.py
@@ -63,8 +63,8 @@ class Query(graphene.ObjectType):
     lessons_for_persons = graphene.List(
         LessonsForPersonType,
         persons=graphene.List(graphene.ID, required=True),
-        start=graphene.Date(required=True),
-        end=graphene.Date(required=True),
+        start=graphene.DateTime(required=True),
+        end=graphene.DateTime(required=True),
     )
 
     extra_marks = FilterOrderList(ExtraMarkType)
@@ -213,8 +213,8 @@ class Query(graphene.ObjectType):
         for person in persons:
             docs, dummies = Documentation.get_documentations_for_person(
                 person,
-                datetime.combine(start, datetime.min.time()),
-                datetime.combine(end, datetime.max.time()),
+                start,
+                end,
             )
 
             lessons_for_person.append(LessonsForPersonType(id=person, lessons=docs + dummies))
diff --git a/aleksis/apps/alsijil/schema/absences.py b/aleksis/apps/alsijil/schema/absences.py
index d05ac55214a36430808bd17ec22cc2f4c6767313..ab006e1d875e053e061d04c9c800ae0c3ef15f2e 100644
--- a/aleksis/apps/alsijil/schema/absences.py
+++ b/aleksis/apps/alsijil/schema/absences.py
@@ -1,6 +1,8 @@
-from datetime import datetime
+import datetime
+from typing import List
 
 from django.core.exceptions import PermissionDenied
+from django.db.models import Q
 
 import graphene
 
@@ -14,8 +16,8 @@ from .participation_status import ParticipationStatusType
 class AbsencesForPersonsCreateMutation(graphene.Mutation):
     class Arguments:
         persons = graphene.List(graphene.ID, required=True)
-        start = graphene.Date(required=True)
-        end = graphene.Date(required=True)
+        start = graphene.DateTime(required=True)
+        end = graphene.DateTime(required=True)
         comment = graphene.String(required=False)
         reason = graphene.ID(required=True)
 
@@ -23,7 +25,16 @@ class AbsencesForPersonsCreateMutation(graphene.Mutation):
     participation_statuses = graphene.List(ParticipationStatusType)
 
     @classmethod
-    def mutate(cls, root, info, persons, start, end, comment, reason):  # noqa
+    def mutate(
+        cls,
+        root,
+        info,
+        persons: List[str | int],
+        start: datetime.datetime,
+        end: datetime.datetime,
+        comment: str,
+        reason: str | int,
+    ):
         participation_statuses = []
 
         persons = Person.objects.filter(pk__in=persons)
@@ -31,17 +42,30 @@ class AbsencesForPersonsCreateMutation(graphene.Mutation):
         for person in persons:
             if not info.context.user.has_perm("alsijil.register_absence_rule", person):
                 raise PermissionDenied()
-            kolego_absence, __ = Absence.objects.get_or_create(
-                date_start=start,
-                date_end=end,
+
+            # Check if there is an existing absence with overlapping datetime
+            absences = Absence.objects.filter(
+                Q(datetime_start__lte=start) | Q(date_start__lte=start.date()),
+                Q(datetime_end__gte=end) | Q(date_end__gte=end.date()),
                 reason_id=reason,
                 person=person,
-                defaults={"comment": comment},
             )
 
+            if len(absences) > 0:
+                kolego_absence = absences.first()
+            else:
+                # Check for same times and create otherwise
+                kolego_absence, __ = Absence.objects.get_or_create(
+                    datetime_start=start,
+                    datetime_end=end,
+                    reason_id=reason,
+                    person=person,
+                    defaults={"comment": comment},
+                )
+
             events = ParticipationStatus.get_single_events(
-                datetime.combine(start, datetime.min.time()),
-                datetime.combine(end, datetime.max.time()),
+                start,
+                end,
                 None,
                 {"person": person},
                 with_reference_object=True,