diff --git a/app/controllers/admin/semester.php b/app/controllers/admin/semester.php
index aa6bf24bd54e4553c8adf18fc7590393914daa31..b8c3f0a056e9fdacd610db1e1b7a9b746c2139b9 100644
--- a/app/controllers/admin/semester.php
+++ b/app/controllers/admin/semester.php
@@ -81,6 +81,8 @@ class Admin_SemesterController extends AuthenticatedController
             $this->semester->ende           = $this->getTimeStamp('ende', '23:59:59');
             $this->semester->vorles_beginn  = $this->getTimeStamp('vorles_beginn');
             $this->semester->vorles_ende    = $this->getTimeStamp('vorles_ende', '23:59:59');
+            $this->semester->sem_wechsel = $this->getTimeStamp('semesterwechsel')?:null;
+
             $this->semester->external_id    = Request::get('external_id');
 
             // Validate
diff --git a/app/controllers/materialien/files.php b/app/controllers/materialien/files.php
index f385a4c845d656c0bc239fe2a433764cfa0951de..d15061f0e73767216031865a30687ab2d7ab6a8b 100644
--- a/app/controllers/materialien/files.php
+++ b/app/controllers/materialien/files.php
@@ -49,12 +49,9 @@ class Materialien_FilesController extends MVVController
 
         // set default semester filter
         if (!isset($this->filter['start_sem.beginn'], $this->filter['end_sem.ende'])) {
-            $sem_time_switch = Config::get()->SEMESTER_TIME_SWITCH;
             // switch semester according to time switch
             // (n weeks before next semester)
-            $current_sem = Semester::findByTimestamp(
-                time() + $sem_time_switch * 7 * 24 * 3600
-            );
+            $current_sem = Semester::findDefault();
             if ($current_sem) {
                 $this->filter['start_sem.beginn'] = $current_sem->beginn;
                 $this->filter['end_sem.ende']     = $current_sem->beginn;
diff --git a/app/controllers/module/module.php b/app/controllers/module/module.php
index 449254a6f5c63d987f1abaa58f42978b6ebb4d2e..29e8a21bfa39598eb0c187fdc1ff99a588bcb5b7 100644
--- a/app/controllers/module/module.php
+++ b/app/controllers/module/module.php
@@ -33,12 +33,9 @@ class Module_ModuleController extends MVVController
 
         // set default semester filter
         if (!isset($this->filter['start_sem.beginn'], $this->filter['end_sem.ende'])) {
-            $sem_time_switch = Config::get()->SEMESTER_TIME_SWITCH;
             // switch semester according to time switch
             // (n weeks before next semester)
-            $current_sem = Semester::findByTimestamp(
-                time() + $sem_time_switch * 7 * 24 * 3600
-            );
+            $current_sem = Semester::findDefault();
             if ($current_sem) {
                 $this->filter['start_sem.beginn'] = $current_sem->beginn;
                 $this->filter['end_sem.ende']     = $current_sem->beginn;
@@ -1159,12 +1156,9 @@ class Module_ModuleController extends MVVController
 
             // set default semester filter
             if (!isset($this->filter['start_sem.beginn']) || !isset($this->filter['end_sem.ende'])) {
-                $sem_time_switch = Config::get()->SEMESTER_TIME_SWITCH;
                 // switch semester according to time switch
                 // (n weeks before next semester)
-                $current_sem = Semester::findByTimestamp(
-                    time() + $sem_time_switch * 7 * 24 * 3600
-                );
+                $current_sem = Semester::findDefault();
                 if ($current_sem) {
                     $this->filter['start_sem.beginn'] = $current_sem->beginn;
                     $this->filter['end_sem.ende'] = $current_sem->beginn;
diff --git a/app/controllers/search/module.php b/app/controllers/search/module.php
index dd555e097c21786799014fa75c78a9bbeb938feb..9fbd66fd7115171fa5eb44397129008904e78b9d 100644
--- a/app/controllers/search/module.php
+++ b/app/controllers/search/module.php
@@ -599,8 +599,7 @@ class Search_ModuleController extends MVVController
             $this->sessSet('selected_semester', Request::option('sem_select'));
         }
         if (!$this->sessGet('selected_semester')) {
-            $semester_switch = (int) Config::get()->SEMESTER_TIME_SWITCH;
-            $current_semester = Semester::findByTimestamp(time() + $semester_switch * 7 * 24 * 60 * 60);
+            $current_semester = Semester::findDefault();
             $this->sessSet('selected_semester', $current_semester['semester_id']);
         }
         $this->selected_semester = Semester::find($this->sessGet('selected_semester'));
diff --git a/app/controllers/search/studiengaenge.php b/app/controllers/search/studiengaenge.php
index 94399fca2f67f74cdfdfedccc9dbd8bdc4813854..aae40691e33c76282c3075291fd37c3c4f9b0514 100644
--- a/app/controllers/search/studiengaenge.php
+++ b/app/controllers/search/studiengaenge.php
@@ -218,9 +218,7 @@ class Search_StudiengaengeController extends MVVController
 
             $this->semesters = $this->getSemester($versionen->findOneBy('id', $this->cur_version_id));
 
-            $semester_time_switch = (int) Config::get()->getValue('SEMESTER_TIME_SWITCH');
-            $cur_semester = Semester::findByTimestamp(time()
-                    + $semester_time_switch * 7 * 24 * 60 * 60);
+            $cur_semester = Semester::findDefault();
 
             $active_semester = $this->sessGet('selected_semester');
             if ($active_semester) {
@@ -339,7 +337,7 @@ class Search_StudiengaengeController extends MVVController
                 $this->url_for('/verlauf/' . $stgteil_id, ['with_courses' => intval(!$this->with_courses)])
             );
             Sidebar::get()->addWidget($widget, 'with_courses');
-            
+
             // add links to export Modulhandbücher as PDF
             $widget = new ActionsWidget();
             $widget->setTitle(_('Aktuelle Modulhandbücher'));
@@ -383,7 +381,7 @@ class Search_StudiengaengeController extends MVVController
                 ->toGroupedArray('category', ['name'], function ($ca) {
                     return array_values($ca);
                 });
-        
+
         $this->all_documents = [];
         // get documents in current selected language with fallback to default language
         // grouped by category
@@ -499,9 +497,7 @@ class Search_StudiengaengeController extends MVVController
     private function setVersionSelectWidget($versions, $url)
     {
 
-        $semester_time_switch = (int) Config::get()->getValue('SEMESTER_TIME_SWITCH');
-        $cur_semester = Semester::findByTimestamp(time()
-            + $semester_time_switch * 7 * 24 * 60 * 60);
+        $cur_semester = Semester::findDefault();
 
         $sidebar = Sidebar::get();
 
diff --git a/app/controllers/shared/contacts.php b/app/controllers/shared/contacts.php
index f2d5ceea6580c6b98d8b7bdcd06c27430dfb23a9..d4a95763e7350136ef0d3667add6b64fb750d9e2 100644
--- a/app/controllers/shared/contacts.php
+++ b/app/controllers/shared/contacts.php
@@ -43,12 +43,9 @@ class Shared_ContactsController extends MVVController
 
         // set default semester filter
         if (!isset($this->filter['start_sem.beginn'], $this->filter['end_sem.ende'])) {
-            $sem_time_switch = Config::get()->SEMESTER_TIME_SWITCH;
             // switch semester according to time switch
             // (n weeks before next semester)
-            $current_sem = Semester::findByTimestamp(
-                time() + $sem_time_switch * 7 * 24 * 3600
-            );
+            $current_sem = Semester::findDefault();
             if ($current_sem) {
                 $this->filter['start_sem.beginn'] = $current_sem->beginn;
                 $this->filter['end_sem.ende']     = $current_sem->beginn;
@@ -443,7 +440,7 @@ class Shared_ContactsController extends MVVController
 
         if (Request::submitted('store_ansprechpartner')) {
             CSRFProtection::verifySecurityToken();
-            
+
             if (!$user_id) {
                 if (Request::get('exansp_name')) {
                     $ext_contact->name = Request::i18n('exansp_name');
@@ -540,7 +537,7 @@ class Shared_ContactsController extends MVVController
 
     public function store_ansprechpartner_action ($contact_range_id, $origin = 'index') {
         CSRFProtection::verifySecurityToken();
-        
+
         $contact_range = MvvContactRange::find($contact_range_id);
         if (!$contact_range) {
             throw new Exception(_('Fehlerhafte Zuordnung!'));
diff --git a/app/controllers/shared/modul.php b/app/controllers/shared/modul.php
index 55644db11b2fb7cc27f5227661423a51e8e62c4b..0c3a39bdc797b802c0d2e64eda7fb1aaa5a5b480 100644
--- a/app/controllers/shared/modul.php
+++ b/app/controllers/shared/modul.php
@@ -49,8 +49,7 @@ class Shared_ModulController extends AuthenticatedController
             }
 
             if (!$semester_id) {
-                $semesterSwitch = (int) Config::get()->SEMESTER_TIME_SWITCH;
-                $currentSemester = Semester::findByTimestamp(time() + $semesterSwitch * 7 * 24 * 60 * 60);
+                $currentSemester = Semester::findDefault();
             } else {
                 $currentSemester = Semester::find($semester_id);
             }
diff --git a/app/controllers/studiengaenge/studiengaenge.php b/app/controllers/studiengaenge/studiengaenge.php
index 108eb61b62060900cd71dde69baf614fe0524649..f6c0573e3cf8eac50e209fd1567dba6c14bc67ca 100644
--- a/app/controllers/studiengaenge/studiengaenge.php
+++ b/app/controllers/studiengaenge/studiengaenge.php
@@ -37,12 +37,9 @@ class Studiengaenge_StudiengaengeController extends MVVController
 
         // set default semester filter
         if (!isset($this->filter['start_sem.beginn'], $this->filter['end_sem.ende'])) {
-            $sem_time_switch = Config::get()->getValue('SEMESTER_TIME_SWITCH');
             // switch semester according to time switch
             // (n weeks before next semester)
-            $current_sem = Semester::findByTimestamp(
-                time() + $sem_time_switch * 7 * 24 * 3600
-            );
+            $current_sem = Semester::findDefault();
             if ($current_sem) {
                 $this->filter['start_sem.beginn'] = $current_sem->beginn;
                 $this->filter['end_sem.ende'] = $current_sem->beginn;
@@ -765,11 +762,9 @@ class Studiengaenge_StudiengaengeController extends MVVController
         // set default semester filter
         if (!isset($filter['start_sem.beginn'])
                 || !isset($filter['end_sem.ende'])) {
-            $sem_time_switch = Config::get()->getValue('SEMESTER_TIME_SWITCH');
             // switch semester according to time switch
             // (n weeks before next semester)
-            $current_sem = Semester::findByTimestamp(time()
-                    + $sem_time_switch * 7 * 24 * 3600);
+            $current_sem = Semester::findDefault();
             if ($current_sem) {
                 $filter['start_sem.beginn'] = $current_sem->beginn;
                 $filter['end_sem.ende'] = $current_sem->beginn;
diff --git a/app/controllers/studiengaenge/versionen.php b/app/controllers/studiengaenge/versionen.php
index 90164adb7964085eab8a729bfe2e8ca80a981313..cb0be78d26ad540e413bd62e8cbd9353d74a40c5 100644
--- a/app/controllers/studiengaenge/versionen.php
+++ b/app/controllers/studiengaenge/versionen.php
@@ -215,12 +215,9 @@ class Studiengaenge_VersionenController extends SharedVersionController
 
             // set default semester filter
             if (!$this->filter['start_sem.beginn'] || !$this->filter['end_sem.ende']) {
-                $sem_time_switch = Config::get()->getValue('SEMESTER_TIME_SWITCH');
-                // switch semester according to time switch
-                // (n weeks before next semester)
-                $current_sem = Semester::findByTimestamp(
-                    time() + $sem_time_switch * 7 * 24 * 3600
-                );
+
+                // new: we use either manual change date or time switch
+                $current_sem = Semester::findDefault();
                 if ($current_sem) {
                     $this->filter['start_sem.beginn'] = $current_sem->beginn;
                     $this->filter['end_sem.ende'] = $current_sem->beginn;
diff --git a/app/views/admin/semester/edit.php b/app/views/admin/semester/edit.php
index ded488d899d6dfa137360052dc79038e0bbb7187..f92a19a883cd9b172cd11071415cfdaa69c4d1f4 100644
--- a/app/views/admin/semester/edit.php
+++ b/app/views/admin/semester/edit.php
@@ -30,10 +30,10 @@
                 'id' => 'description',
             ]) ?>
         </label>
-        
+
         <label>
             <?= _('Externe ID') ?>
-            
+
             <input type="text" name="external_id" value="<?= htmlReady($semester->external_id) ?>" maxlength="50">
         </label>
     </fieldset>
@@ -44,7 +44,7 @@
         </legend>
 
         <label class="col-3">
-            <?= _('Beginn') ?>
+            <span class="required"><?= _('Beginn') ?></span>
 
             <? if ($semester->absolute_seminars_count > 0): ?>
                 <?= tooltipIcon(_('Das Startdatum kann nur bei Semestern geändert werden, in denen keine Veranstaltungen liegen!'), true) ?>
@@ -61,7 +61,7 @@
         </label>
 
         <label class="col-3">
-            <?= _('Ende') ?>
+            <span class="required"><?= _('Ende') ?></span>
 
             <input required type="text" id="ende" name="ende"
                    <? if (isset($errors['ende'])) echo 'class="invalid"'; ?>
@@ -76,7 +76,7 @@
         </legend>
 
         <label class="col-3">
-            <?= _('Beginn') ?>
+            <span class="required"><?= _('Beginn') ?></span>
 
             <input required type="text" id="vorles_beginn" name="vorles_beginn"
                    <? if (isset($errors['vorles_beginn'])) echo 'class="invalid"'; ?>
@@ -85,7 +85,7 @@
         </label>
 
         <label class="col-3">
-            <?= _('Ende') ?>
+            <span class="required"><?= _('Ende') ?></span>
 
             <input required type="text" id="vorles_ende" name="vorles_ende"
                     <? if (isset($errors['vorles_ende'])) echo 'class="invalid"'; ?>
@@ -93,6 +93,20 @@
                    value="<? if ($semester->vorles_ende) echo date('d.m.Y', $semester->vorles_ende); ?>">
         </label>
    </fieldset>
+    <fieldset>
+        <legend>
+         <?= _('Tatsächlicher Semesterwechsel') ?>
+        </legend>
+
+        <label class="col-3">
+            <span><?= _('Beginn') ?></span>
+            <?= tooltipIcon(_('Optional. Wird kein Datum angegeben, wird das Wochen-Offset in SEMESTER_TIME_SWITCH berücksichtigt.')) ?>
+            <input type="text" id="semesterwechsel" name="semesterwechsel"
+                <? if (isset($errors['semesterwechsel'])) echo 'class="invalid"'; ?>
+                   data-date-picker='{"<=":"#beginn"}'
+                   value="<? if ($semester->sem_wechsel) echo date('d.m.Y', $semester->sem_wechsel) ?>">
+        </label>
+    </fieldset>
 
     <footer data-dialog-button>
         <?= Studip\Button::createAccept(_('Speichern')) ?>
diff --git a/app/views/admin/semester/index.php b/app/views/admin/semester/index.php
index 2ac8559a8df3810dd6872bb23a8dec799a58af04..b8bf06f687a4a56faa9b2e4e43bcff3898c3eede 100644
--- a/app/views/admin/semester/index.php
+++ b/app/views/admin/semester/index.php
@@ -23,6 +23,7 @@
             <th><?= _('Kürzel') ?></th>
             <th><?= _('Zeitraum') ?></th>
             <th><?= _('Veranstaltungszeitraum') ?></th>
+            <th><?= _('Tatsächlicher Semesterwechsel') ?></th>
             <th><?= _('Veranstaltungen') ?></th>
             <th>&nbsp;</th>
         </tr>
@@ -71,6 +72,9 @@
                 -
                 <?= strftime('%x', $semester->vorles_ende) ?>
             </td>
+            <td>
+                <?= Semester::getSemChangeDate($semester) ?>
+            </td>
             <td>
                 <?= $semester->absolute_seminars_count ?>
                 <?= sprintf(_('(+%u implizit)'),
@@ -144,7 +148,7 @@
     </tbody>
     <tfoot>
         <tr>
-            <td colspan="7">
+            <td colspan="8">
                 <?= Studip\Button::create(_('Markierte Einträge löschen'), 'delete', [
                         'data-confirm' => _('Sollen die Semester wirklich gelöscht werden?')
                 ]) ?>
diff --git a/db/migrations/5.2.12_add_semwechsel_field.php b/db/migrations/5.2.12_add_semwechsel_field.php
new file mode 100644
index 0000000000000000000000000000000000000000..4bb191cceace07f6064ccf10a107f4179ecf2aef
--- /dev/null
+++ b/db/migrations/5.2.12_add_semwechsel_field.php
@@ -0,0 +1,32 @@
+<?php
+
+
+class AddSemwechselField extends Migration
+{
+    public function description()
+    {
+        return 'Add field sem_wechsel to table semester_data';
+    }
+
+
+    public function up()
+    {
+        $db = DBManager::get();
+
+        $db->exec(
+            "ALTER TABLE `semester_data`
+            ADD `sem_wechsel` INT(11) UNSIGNED NULL AFTER `ende`"
+        );
+    }
+
+
+    public function down()
+    {
+        $db = DBManager::get();
+
+        $db->exec(
+            "ALTER TABLE `semester_data` DROP `sem_wechsel`"
+        );
+
+    }
+}
diff --git a/lib/classes/SemBrowse.class.php b/lib/classes/SemBrowse.class.php
index 82b683fbfa9a058a9484df59a9722aa562d7b399..fd4b2dc320ee0b3a9f059198601511a20743c2dc 100644
--- a/lib/classes/SemBrowse.class.php
+++ b/lib/classes/SemBrowse.class.php
@@ -1313,9 +1313,7 @@ class SemBrowse {
     {
         $default_sem = $_SESSION['_default_sem'];
         if (!$default_sem) {
-            $semester_time_switch = (int) Config::get()->getValue('SEMESTER_TIME_SWITCH');
-            $current_sem = Semester::findByTimestamp(time()
-                + $semester_time_switch * 7 * 24 * 60 * 60);
+            $current_sem = Semester::findDefault();
             $default_sem = $current_sem->id;
         }
 
diff --git a/lib/classes/coursewizardsteps/BasicDataWizardStep.php b/lib/classes/coursewizardsteps/BasicDataWizardStep.php
index 0f0a3a91e008ded4c2823e9545d01317e634230e..14793ea319e132a12f5639051d394a953652951c 100644
--- a/lib/classes/coursewizardsteps/BasicDataWizardStep.php
+++ b/lib/classes/coursewizardsteps/BasicDataWizardStep.php
@@ -84,15 +84,13 @@ class BasicDataWizardStep implements CourseWizardStep
                         !$values['start_time'] && Request::isXhr()) {
                         $values['start_time'] = $s->beginn;
                     }
-                } else {
-                    if ((time() >= $s->beginn - Config::get()->SEMESTER_TIME_SWITCH * 86400 * 7)
-                        && (time() < $s->ende - Config::get()->SEMESTER_TIME_SWITCH * 86400 * 7)) {
-                        $values['start_time'] = $s->beginn;
-                    }
                 }
                 $semesters[] = $s;
             }
         }
+        if (!$values['start_time']) {
+            $values['start_time'] = Semester::findDefault()->beginn;
+        }
         if ($values['studygroup'] && (!count($typestruct) || !$values['institute']) ) {
             $message = sprintf(_('Die Konfiguration der Studiengruppen ist unvollständig. ' .
                 'Bitte wenden Sie sich an [die Stud.IP-Administration]%s .'),
diff --git a/lib/classes/globalsearch/GlobalSearchModule.php b/lib/classes/globalsearch/GlobalSearchModule.php
index 7f06faf51219ba1a56cdcd84193b9ef7ffe4a937..084e3279892a641e79c3bc0d2df17ddee8581c3a 100644
--- a/lib/classes/globalsearch/GlobalSearchModule.php
+++ b/lib/classes/globalsearch/GlobalSearchModule.php
@@ -214,8 +214,7 @@ abstract class GlobalSearchModule
      */
     public static function getCurrentSemester()
     {
-        $sem_time_switch = Config::get()->SEMESTER_TIME_SWITCH;
-        $current_semester = Semester::findByTimestamp(time() + $sem_time_switch * 7 * 24 * 3600);
+        $current_semester = Semester::findDefault();
 
         return (int)$current_semester['beginn'];
     }
diff --git a/lib/models/Semester.class.php b/lib/models/Semester.class.php
index 10f21ae4352785c1511021ad4d778867dab8228d..84d90abb668f6289d961d799ec0b1fbcf312cb1a 100644
--- a/lib/models/Semester.class.php
+++ b/lib/models/Semester.class.php
@@ -477,4 +477,43 @@ class Semester extends SimpleORMap
     {
         StudipCacheFactory::getCache()->expire('DB_SEMESTER_DATA');
     }
+
+    /*
+     * for Admin
+     */
+    public static function getSemChangeDate($semester)
+    {
+
+        if ($semester->sem_wechsel) {
+            $semchangedate = strftime('%x', $semester->sem_wechsel);
+        } else {
+            $semesterSwitch = (int) Config::get()->SEMESTER_TIME_SWITCH;
+            $currentSem = $semester->beginn - $semesterSwitch * 7 * 24 * 60 * 60;
+            $semchangedate = strftime('%x', $currentSem);
+        }
+
+        return $semchangedate;
+    }
+
+    public static function findDefault()
+    {
+        $all_sems = self::getAll();
+
+        // $all_sems now contents only semesters with valid change dates, either manual or SEMESTER_TIME_SWITCH
+        foreach (array_reverse($all_sems) as $semester) {
+            if ($semester['ende'] <= time()) {
+                continue;
+            }
+
+            if (in_array('sem_wechsel', $semester->known_slots) && $semester['sem_wechsel']) {
+                $timestamp = $semester['sem_wechsel'];
+            } else {
+                $timestamp = $semester['beginn'] - (int)Config::get()->SEMESTER_TIME_SWITCH * 7 * 24 * 60 * 60;
+            }
+
+            if ($timestamp <= time()) {
+                return  $semester;
+            }
+        }
+    }
 }
diff --git a/lib/seminar_open.php b/lib/seminar_open.php
index c48ce07c6d36c142843ef13e506b4bc15fbdb0f5..adb3e429c9d33c7fb54e3c3764baf382f0d2d597 100644
--- a/lib/seminar_open.php
+++ b/lib/seminar_open.php
@@ -95,8 +95,7 @@ if ($auth->is_authenticated() && is_object($user) && $user->id != "nobody") {
         UserConfig::get($user->id)->store('LAST_LOGIN_TIMESTAMP', UserConfig::get($user->id)->CURRENT_LOGIN_TIMESTAMP);
         UserConfig::get($user->id)->store('CURRENT_LOGIN_TIMESTAMP', $_SESSION['SessionStart']);
         //find current semester and store it in $_SESSION['_default_sem']
-        $current_sem = Semester::findByTimestamp(time() + Config::get()->SEMESTER_TIME_SWITCH * 7 * 24 * 60 * 60);
-        if (!$current_sem ) $current_sem = Semester::findCurrent();
+        $current_sem = Semester::findDefault();
         $_SESSION['_default_sem'] = $current_sem->semester_id;
         //redirect user to another page if he want to, redirect is deferred to allow plugins to catch the UserDidLogin notification
         if (UserConfig::get($user->id)->PERSONAL_STARTPAGE > 0 && $i_page == "index.php" && !$perm->have_perm("root")) {