diff --git a/NAMESPACE b/NAMESPACE
index e2c12f462a432af48614518c8b9e66cdc7131c31..5bf430846b19ed52a8584cd01af01ad653b934ec 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -51,6 +51,8 @@ export(PP.rate.terminalBonusFund)
 export(PP.rate.totalInterest)
 export(PP.rate.totalInterest2)
 export(ProfitParticipation)
+export(age.exactRounded)
+export(age.yearDifference)
 export(applyHook)
 export(contractGrid)
 export(contractGridPremium)
diff --git a/R/HelperFunctions.R b/R/HelperFunctions.R
index b8e92c3553bb27a76d9ab964af3ed1e1391f2c35..f813ea7fddb041927ee2e687cc85ccf879cda99e 100644
--- a/R/HelperFunctions.R
+++ b/R/HelperFunctions.R
@@ -182,6 +182,32 @@ deathBenefit.annuityDecreasing = function(interest) {
   }
 }
 
+
+#' Calculate the age of the insured based on exact age at contract closing, rounded
+#' to the nearest birthday.
+#'
+#' @param params The parameters of the contract.
+#' @param values Unused by default (already calculated values of the contract)
+#'
+#' @export
+age.exactRounded = function(params, values) {
+  round(time_length(
+    interval(params$ContractData$birthDate, params$ContractData$contractClosing),
+  "years"))
+}
+
+#' Calculate the age of the insured based on the difference of the bith year and
+#' contract closing year.
+#'
+#' @param params The parameters of the contract.
+#' @param values Unused by default (already calculated values of the contract)
+#'
+#' @export
+age.yearDifference = function(params, values) {
+  year(params$ContractData$contractClosing) - year(params$ContractData$birthDate)
+}
+
+
 #' Defines a frequency charge (surcharge for monthly/quarterly/semiannual) premium payments #'
 #' Tariffs are typically calculated with yearly premium installments. When
 #' premiums are paid more often then one a year (in advance), the insurance
@@ -648,3 +674,5 @@ sumPaddedArrays = function(arr1 = NULL, arr2 = NULL, pad1 = 0, pad2 = 0) {
 }
 
 
+
+
diff --git a/R/InsuranceContract.R b/R/InsuranceContract.R
index 72ea0ca81c8e563356a75ba69bb6ab68f0f85318..aa2112be162839af9d509fc4e5ad5d320cfa6931 100644
--- a/R/InsuranceContract.R
+++ b/R/InsuranceContract.R
@@ -884,30 +884,63 @@ InsuranceContract = R6Class(
             args = list(...);
             # TODO-blocks
 
-            # Calculate YOB, age, contract closing etc. from each other
+            if (getOption('LIC.debug.consolidateContractData', FALSE)) {
+                browser();
+            }
+            # YOB is deprecated in favor of birthDate. If it is given, use January 1
+            if (is.null(self$Parameters$ContractData$birthDate) && !is.null(self$Parameters$ContractData$YOB)) {
+                self$Parameters$ContractData$birthDate = make_date(self$Parameters$ContractData$YOB, 1, 1)
+            }
+
+            # Calculate date/year of birth, age, contract closing etc. from each other
             # 1. Contract date (if not given) is NOW, unless age + YOB is given => Then year is derived as YOB+age
             if (is.null(self$Parameters$ContractData$contractClosing)) {
-                if (!is.null(self$Parameters$ContractData$age) && !is.null(self$Parameters$ContractData$YOB)) {
-                    # Use current day, but determine year from YOB and age
-                    self$Parameters$ContractData$contractClosing = Sys.Date() %>%
-                        'year<-'(self$Parameters$ContractData$YOB + self$Parameters$ContractData$age);
+                # Default is contractClosing is NOW:
+                self$Parameters$ContractData$contractClosing = Sys.Date()
+
+                # However, if age and DOB / YOB is given, calculate contract closing from that:
+                # age is given (and not a function that calculates age from DOB and Contract closing)
+                if (!is.null(self$Parameters$ContractData$age) &&
+                    !is.function(self$Parameters$ContractData$age)
+                ) {
+                    if (!is.null(self$Parameters$ContractData$birthDate)) {
+                        ag = self$Parameters$ContractData$age
+                        # Whole years are added as period (so the day stays the same), remaining fractions are added as dyears
+                        self$Parameters$ContractData$contractClosing = as.Date(self$Parameters$ContractData$birthDate +
+                            years(floor(self$Parameters$ContractData$age)) +
+                            dyears(self$Parameters$ContractData$age %% 1))
+                        # TODO: Always start at the nearest beginning of a month? Or leave the contract closing at any day?
+                    }
                 }
             }
 
-            # 2. Current age: If YOB is given, calculate from contract closing and YOB, otherwise assume 40
-            if (is.null(self$Parameters$ContractData$age)) {
-                if (is.null(self$Parameters$ContractData$YOB)) {
-                    self$Parameters$ContractData$age = 40; # No information to derive age => Assume 40
-                    warning("InsuranceContract: Missing age, no information to derive age from YOB and contractClosing => Assuming default age 40. Tariff: ", self$tarif$name)
+            # 2. Current age: If age is given, use it
+            if (!is.null(self$Parameters$ContractData$age)) {
+                self$Parameters$ContractData$age = valueOrFunction(
+                    self$Parameters$ContractData$age,
+                    params = self$Parameters, values = self$Values);
+            } else {
+            # 3. Otherwise, either use the birth date to calculate the age
+                if (!is.null(self$Parameters$ContractData$birthDate)) {
+                    # TODO: Decide for variant 1 or 2...
+                    # Variant 1: Exact age rounded to the nearest whole number
+                    self$Parameters$ContractData$age = age.exactRounded(self$Parameters, self$Values)
+                    # Variant 2: Year of contract closing - YOB
+                    self$Parameters$ContractData$age = age.yearDifference(self$Parameters, self$Values)
                 } else {
-                    self$Parameters$ContractData$age = year(self$Parameters$ContractData$contractClosing) -
-                        self$Parameters$ContractData$YOB;
+            # 4. Or use age=40 as default
+                    self$Parameters$ContractData$age = 40
+                    warning("InsuranceContract: Missing age, no information to derive age from YOB and contractClosing => Assuming default age 40. Tariff: ", self$tarif$name)
                 }
             }
-            if (is.null(self$Parameters$ContractData$YOB)) {
-                self$Parameters$ContractData$YOB = year(self$Parameters$ContractData$contractClosing) - self$Parameters$ContractData$age;
+            if (is.null(self$Parameters$ContractData$birthDate)) {
+                self$Parameters$ContractData$birthDate = as.Date(self$Parameters$ContractData$contractClosing -
+                    years(floor(self$Parameters$ContractData$age)) -
+                    dyears(self$Parameters$ContractData$age %% 1))
             }
 
+
+
             # Evaluate policy period, i.e. if a function is used, calculate its numeric value
             self$Parameters$ContractData$policyPeriod = valueOrFunction(
                 self$Parameters$ContractData$policyPeriod,
@@ -940,12 +973,15 @@ InsuranceContract = R6Class(
             #### #
             # For joint lives, some parameters can be given multiple times: age, sex
             # Collect all given values into one vector!
+
+            # TODO: First person has birthDate handled properly, handle all other persons, too!
             age = unlist(args[names(args) == "age"], use.names = FALSE)
-            if (!is.null(age)) {
-                self$Parameters$ContractData$age = age;
+            if (!is.null(age) && length(age) > 1) {
+                self$Parameters$ContractData$age = c(self$Parameters$ContractData$age[[1]], tail(age, -1));
+                # TODO: Calculate ages for all other persons, too. Or rather, allow multiple birthDate values, too
             }
             sex = unlist(args[names(args) == "sex"], use.names = FALSE)
-            if (!is.null(sex)) {
+            if (!is.null(sex) && length(sex) > 1) {
                 self$Parameters$ContractData$sex = sex;
             }
             if (is.null(self$Parameters$ContractData$ageDifferences)) {
diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R
index 96cbb735fc55a2bb931984640c3d37ba894787e0..ba76034a457b4c2a72aa06b4cf6a75b67e1da57c 100644
--- a/R/InsuranceParameters.R
+++ b/R/InsuranceParameters.R
@@ -249,8 +249,11 @@ InsuranceContract.Values = list(
 #'     \item{\code{$initialCapital}}{Reserve/Capital that is already available
 #'               at contract inception, e.g. from a previous contract. No tax
 #'               or acquisition costs are applied to this capital.}
-#'     \item{\code{$YOB}}{Year of birth of the insured, used to determine the
+#'     \item{\code{$YOB (deprecated)}}{Year of birth of the insured, used to determine the
 #'               age for the application of the mortality table}
+#'     \item{\code{$birthDate}}{Date  of birth of the insured, used to determine the
+#'               age for the application of the mortality table. Alternatively,
+#'               the year alone can be passed as \code{YOB}.}
 #'     \item{\code{$age}}{Age of the insured}
 #'     \item{\code{$technicalAge}}{Technical age of the insured (when the age
 #'               for the application of the mortality table does not coincide
@@ -500,6 +503,7 @@ InsuranceContract.ParameterDefaults = list(
     ContractData = list(
         id = "Hauptvertrag",
         sumInsured = 100000,
+        birthDate = NULL,
         YOB = NULL,
         age = NULL,
         technicalAge = NULL,
diff --git a/R/InsuranceTarif.R b/R/InsuranceTarif.R
index f63a0549e5a464f1b54190ad8510e602be5c1b8d..a3e53626a6a0e8c1a8052d90f651b56aa06c8815 100644
--- a/R/InsuranceTarif.R
+++ b/R/InsuranceTarif.R
@@ -317,7 +317,7 @@ InsuranceTarif = R6Class(
       if (getOption('LIC.debug.getAges', FALSE)) {
         browser();
       }
-      ages = ages(params$ActuarialBases$mortalityTable, YOB = params$ContractData$YOB);
+            ages = ages(params$ActuarialBases$mortalityTable, YOB = year(params$ContractData$birthDate));
       age = params$ContractData$technicalAge;
       if (age > 0) {
         ages = ages[-age:-1];
@@ -335,12 +335,12 @@ InsuranceTarif = R6Class(
       }
       age = params$ContractData$technicalAge;
       ages = self$getAges(params);
-      q = MortalityTables::deathProbabilities(params$ActuarialBases$mortalityTable, YOB = params$ContractData$YOB, ageDifferences = params$ContractData$ageDifferences);
+      q = MortalityTables::deathProbabilities(params$ActuarialBases$mortalityTable, YOB = year(params$ContractData$birthDate), ageDifferences = params$ContractData$ageDifferences);
       if (age > 0) {
         q    = q[-age:-1];
       }
       if (!is.null(params$ActuarialBases$invalidityTable)) {
-        i = MortalityTables::deathProbabilities(params$ActuarialBases$invalidityTable, YOB = params$ContractData$YOB, ageDifferences = params$ContractData$ageDifferences);
+        i = MortalityTables::deathProbabilities(params$ActuarialBases$invalidityTable, YOB = year(params$ContractData$birthDate), ageDifferences = params$ContractData$ageDifferences);
         if (age > 0) {
           i    = i[-age:-1];
         }
diff --git a/R/exportInsuranceContractExample.R b/R/exportInsuranceContractExample.R
index bf823ec2a1702d7beecc2c052fd1a108593b9312..ed1acebc3d4ef283c2a6407e0909016a0c605790 100644
--- a/R/exportInsuranceContractExample.R
+++ b/R/exportInsuranceContractExample.R
@@ -59,7 +59,7 @@ exportInsuranceContractExample = function(contract, prf = 10, outdir = ".", base
         if (!missing(extraname) && !is.null(extraname)) {
             basename = paste(basename, "_", extraname, sep = "")
         }
-        basename = paste(basename, "_RZ", sprintf("%.2f", contract$Parameters$ActuarialBases$i), "_x", contract$Parameters$ContractData$age, "_YoB", contract$Parameters$ContractData$YOB, "_LZ", contract$Parameters$ContractData$policyPeriod, "_PrZ", contract$Parameters$ContractData$premiumPeriod, "_VS", contract$Parameters$ContractData$sumInsured, sep = "" )
+        basename = paste(basename, "_RZ", sprintf("%.2f", contract$Parameters$ActuarialBases$i), "_x", contract$Parameters$ContractData$age, "_YoB", year(params$ContractData$birthDate), "_LZ", contract$Parameters$ContractData$policyPeriod, "_PrZ", contract$Parameters$ContractData$premiumPeriod, "_VS", contract$Parameters$ContractData$sumInsured, sep = "" )
     }
 
     filename = paste(basename, ".xlsx", sep = "");
diff --git a/R/exportInsuranceContract_xlsx.R b/R/exportInsuranceContract_xlsx.R
index cc3d689deb644d895cec10b77d009c3b383cdf6b..d3d1f93480c0adf292f5280f9898e65fb2d2da75 100644
--- a/R/exportInsuranceContract_xlsx.R
+++ b/R/exportInsuranceContract_xlsx.R
@@ -239,7 +239,7 @@ getContractBlockValues = function(contract) {
       "Sum insured"         = contract$Parameters$ContractData$sumInsured,
       "Mortality table"     = contract$Parameters$ActuarialBases$mortalityTable@name,
       i                     = contract$Parameters$ActuarialBases$i,
-      "YOB"                 = contract$Parameters$ContractData$YOB,
+      "Birth Date"          = contract$Parameters$ContractData$birthDate,
       "Age"                 = contract$Parameters$ContractData$age,
       "Technical Age"       = contract$Parameters$ContractData$technicalAge,
       "Policy duration"     = contract$Parameters$ContractData$policyPeriod,
diff --git a/man/InsuranceContract.ParameterDefaults.Rd b/man/InsuranceContract.ParameterDefaults.Rd
index b6d01ac2810c1cb021e5bbc02973bb4c0069a098..a50140771c264390b9845967000404e23bcb700e 100644
--- a/man/InsuranceContract.ParameterDefaults.Rd
+++ b/man/InsuranceContract.ParameterDefaults.Rd
@@ -44,8 +44,11 @@ default = "Hauptvertrag"}
 \item{\code{$initialCapital}}{Reserve/Capital that is already available
 at contract inception, e.g. from a previous contract. No tax
 or acquisition costs are applied to this capital.}
-\item{\code{$YOB}}{Year of birth of the insured, used to determine the
+\item{\code{$YOB (deprecated)}}{Year of birth of the insured, used to determine the
 age for the application of the mortality table}
+\item{\code{$birthDate}}{Date  of birth of the insured, used to determine the
+age for the application of the mortality table. Alternatively,
+the year alone can be passed as \code{YOB}.}
 \item{\code{$age}}{Age of the insured}
 \item{\code{$technicalAge}}{Technical age of the insured (when the age
 for the application of the mortality table does not coincide
diff --git a/man/age.exactRounded.Rd b/man/age.exactRounded.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..71ae22f31416cc8ff7db132101bd9fc38b2f7524
--- /dev/null
+++ b/man/age.exactRounded.Rd
@@ -0,0 +1,18 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/HelperFunctions.R
+\name{age.exactRounded}
+\alias{age.exactRounded}
+\title{Calculate the age of the insured based on exact age at contract closing, rounded
+to the nearest birthday.}
+\usage{
+age.exactRounded(params, values)
+}
+\arguments{
+\item{params}{The parameters of the contract.}
+
+\item{values}{Unused by default (already calculated values of the contract)}
+}
+\description{
+Calculate the age of the insured based on exact age at contract closing, rounded
+to the nearest birthday.
+}
diff --git a/man/age.yearDifference.Rd b/man/age.yearDifference.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..b972916c306f66b0347e650b19202110b394ee27
--- /dev/null
+++ b/man/age.yearDifference.Rd
@@ -0,0 +1,18 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/HelperFunctions.R
+\name{age.yearDifference}
+\alias{age.yearDifference}
+\title{Calculate the age of the insured based on the difference of the bith year and
+contract closing year.}
+\usage{
+age.yearDifference(params, values)
+}
+\arguments{
+\item{params}{The parameters of the contract.}
+
+\item{values}{Unused by default (already calculated values of the contract)}
+}
+\description{
+Calculate the age of the insured based on the difference of the bith year and
+contract closing year.
+}