diff --git a/apps/files_sharing/api/local.php b/apps/files_sharing/api/local.php
index eb0e0e0d846dde704a41af4234abb413a415ddbd..87025998b3dbdcd44194f567a8faee0169824c16 100644
--- a/apps/files_sharing/api/local.php
+++ b/apps/files_sharing/api/local.php
@@ -258,6 +258,7 @@ class Local {
 		$itemSource = self::getFileId($path);
 		$itemSourceName = $itemSource;
 		$itemType = self::getItemType($path);
+		$expirationDate = null;
 
 		if($itemSource === null) {
 			return new \OC_OCS_Result(null, 404, "wrong path, file/folder doesn't exist.");
@@ -286,6 +287,14 @@ class Local {
 				// read, create, update (7) if public upload is enabled or
 				// read (1) if public upload is disabled
 				$permissions = $publicUpload === 'true' ? 7 : 1;
+
+				// Get the expiration date
+				try {
+					$expirationDate = isset($_POST['expireDate']) ? self::parseDate($_POST['expireDate']) : null;
+				} catch (\Exception $e) {
+					return new \OC_OCS_Result(null, 404, 'Invalid Date. Format must be YYYY-MM-DD.');
+				}
+
 				break;
 			default:
 				return new \OC_OCS_Result(null, 400, "unknown share type");
@@ -302,10 +311,15 @@ class Local {
 					$shareType,
 					$shareWith,
 					$permissions,
-					$itemSourceName
-					);
+					$itemSourceName,
+					$expirationDate
+			);
 		} catch (HintException $e) {
-			return new \OC_OCS_Result(null, 400, $e->getHint());
+			if ($e->getCode() === 0) {
+				return new \OC_OCS_Result(null, 400, $e->getHint());
+			} else {
+				return new \OC_OCS_Result(null, $e->getCode(), $e->getHint());
+			}
 		} catch (\Exception $e) {
 			return new \OC_OCS_Result(null, 403, $e->getMessage());
 		}
@@ -537,6 +551,30 @@ class Local {
 		}
 	}
 
+	/**
+	 * Make sure that the passed date is valid ISO 8601
+	 * So YYYY-MM-DD
+	 * If not throw an exception
+	 *
+	 * @param string $expireDate
+	 *
+	 * @throws \Exception
+	 * @return \DateTime
+	 */
+	private static function parseDate($expireDate) {
+		if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $expireDate) === 0) {
+			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
+		}
+
+		$date = new \DateTime($expireDate);
+
+		if ($date === false) {
+			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
+		}
+
+		return $date;
+	}
+
 	/**
 	 * get file ID from a given path
 	 * @param string $path
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
index 3bd568e47af98c2b66da17a2228fc4c5179e7559..d0ee71cec5a28334d6fa688b1edae72fd67a054b 100644
--- a/apps/files_sharing/tests/api.php
+++ b/apps/files_sharing/tests/api.php
@@ -1487,4 +1487,146 @@ class Test_Files_Sharing_Api extends TestCase {
 		$config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
 
 	}
+
+	public function datesProvider() {
+		$date = new \DateTime();
+		$date->add(new \DateInterval('P5D'));
+
+		$year = (int)$date->format('Y');
+
+		return [
+			[$date->format('Y-m-d'), true],
+			[$year+1 . '-1-1', false],
+			[$date->format('Y-m-dTH:m'), false],
+			['abc', false],
+			[$date->format('Y-m-d') . 'xyz', false],
+		];
+	}
+
+	/**
+	 * Make sure only ISO 8601 dates are accepted
+	 *
+	 * @dataProvider datesProvider
+	 */
+	public function testPublicLinkExpireDate($date, $valid) {
+		$_POST['path'] = $this->folder;
+		$_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
+		$_POST['expireDate'] = $date;
+
+		$result = \OCA\Files_Sharing\API\Local::createShare([]);
+
+		if ($valid === false) {
+			$this->assertFalse($result->succeeded());
+			$this->assertEquals(404, $result->getStatusCode());
+			$this->assertEquals('Invalid Date. Format must be YYYY-MM-DD.', $result->getMeta()['message']);
+			return;
+		}
+
+		$this->assertTrue($result->succeeded());
+
+		$data = $result->getData();
+		$this->assertTrue(is_string($data['token']));
+
+		// check for correct link
+		$url = \OC::$server->getURLGenerator()->getAbsoluteURL('/index.php/s/' . $data['token']);
+		$this->assertEquals($url, $data['url']);
+
+
+		$share = $this->getShareFromId($data['id']);
+		$items = \OCP\Share::getItemShared('file', $share['item_source']);
+		$this->assertTrue(!empty($items));
+
+		$item = reset($items);
+		$this->assertTrue(is_array($item));
+		$this->assertEquals($date, substr($item['expiration'], 0, 10));
+
+		$fileinfo = $this->view->getFileInfo($this->folder);
+		\OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+	}
+
+	public function testCreatePublicLinkExpireDateValid() {
+		$config = \OC::$server->getConfig();
+
+		// enforce expire date, by default 7 days after the file was shared
+		$config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
+		$config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
+
+		$date = new \DateTime();
+		$date->add(new \DateInterval('P5D'));
+
+		$_POST['path'] = $this->folder;
+		$_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
+		$_POST['expireDate'] = $date->format('Y-m-d');
+
+		$result = \OCA\Files_Sharing\API\Local::createShare([]);
+
+		$this->assertTrue($result->succeeded());
+
+		$data = $result->getData();
+		$this->assertTrue(is_string($data['token']));
+
+		// check for correct link
+		$url = \OC::$server->getURLGenerator()->getAbsoluteURL('/index.php/s/' . $data['token']);
+		$this->assertEquals($url, $data['url']);
+
+
+		$share = $this->getShareFromId($data['id']);
+		$items = \OCP\Share::getItemShared('file', $share['item_source']);
+		$this->assertTrue(!empty($items));
+
+		$item = reset($items);
+		$this->assertTrue(is_array($item));
+		$this->assertEquals($date->format('Y-m-d'), substr($item['expiration'], 0, 10));
+
+		$fileinfo = $this->view->getFileInfo($this->folder);
+		\OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+
+		$config->setAppValue('core', 'shareapi_default_expire_date', 'no');
+		$config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+	}
+
+	public function testCreatePublicLinkExpireDateInvalidFuture() {
+		$config = \OC::$server->getConfig();
+
+		// enforce expire date, by default 7 days after the file was shared
+		$config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
+		$config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
+
+		$date = new \DateTime();
+		$date->add(new \DateInterval('P8D'));
+
+		$_POST['path'] = $this->folder;
+		$_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
+		$_POST['expireDate'] = $date->format('Y-m-d');
+
+		$result = \OCA\Files_Sharing\API\Local::createShare([]);
+
+		$this->assertFalse($result->succeeded());
+		$this->assertEquals(404, $result->getStatusCode());
+		$this->assertEquals('Cannot set expiration date. Shares cannot expire later than 7 after they have been shared', $result->getMeta()['message']);
+
+		$config->setAppValue('core', 'shareapi_default_expire_date', 'no');
+		$config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+	}
+
+	public function testCreatePublicLinkExpireDateInvalidPast() {
+		$config = \OC::$server->getConfig();
+
+		$date = new \DateTime();
+		$date->sub(new \DateInterval('P8D'));
+
+		$_POST['path'] = $this->folder;
+		$_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
+		$_POST['expireDate'] = $date->format('Y-m-d');
+
+		$result = \OCA\Files_Sharing\API\Local::createShare([]);
+
+		$this->assertFalse($result->succeeded());
+		$this->assertEquals(404, $result->getStatusCode());
+		$this->assertEquals('Cannot set expiration date. Expiration date is in the past', $result->getMeta()['message']);
+
+		$config->setAppValue('core', 'shareapi_default_expire_date', 'no');
+		$config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+	}
+
 }
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index c245f0f88a9199ff19df4e9e538c2741d252d5f0..d0c69badb468d00880902d9c5a6a189e3a502928 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -649,6 +649,21 @@ class Share extends Constants {
 			$permissions = (int)$permissions & ~\OCP\Constants::PERMISSION_DELETE;
 		}
 
+		//Validate expirationDate
+		if ($expirationDate !== null) {
+			try {
+				/*
+				 * Reuse the validateExpireDate.
+				 * We have to pass time() since the second arg is the time
+				 * the file was shared, since it is not shared yet we just use
+				 * the current time.
+				 */
+				$expirationDate = self::validateExpireDate($expirationDate->format('Y-m-d'), time(), $itemType, $itemSource);
+			} catch (\Exception $e) {
+				throw new \OC\HintException($e->getMessage(), $e->getMessage(), 404);
+			}
+		}
+
 		// Verify share type and sharing conditions are met
 		if ($shareType === self::SHARE_TYPE_USER) {
 			if ($shareWith == $uidOwner) {