diff --git a/bleeding.js b/bleeding.js
index 01fc4ce78b942c2ceb28642883adfe7d534845c3..31dc8c69756e98fa1feef6891ed26847539dd353 100644
--- a/bleeding.js
+++ b/bleeding.js
@@ -10,7 +10,9 @@ import styles from './styles'
 import { saveBleeding } from './db'
 import { formatDateForViewHeader } from './format'
 import { bleeding as labels } from './labels'
-import getCycleDay from './get-cycle-day'
+import cycleDayModule from './get-cycle-day-number'
+
+const getCycleDayNumber = cycleDayModule()
 
 export default class Bleeding extends Component {
   constructor(props) {
@@ -39,7 +41,7 @@ export default class Bleeding extends Component {
     return (
       <View style={styles.container}>
         <Text style={styles.welcome}>{formatDateForViewHeader(day.date)}</Text>
-        <Text>Cycle day {getCycleDay()}</Text>
+        <Text>Cycle day {getCycleDayNumber(day.date)}</Text>
         <Text>Bleeding</Text>
         <RadioForm
           radio_props={bleedingRadioProps}
diff --git a/calendar.js b/calendar.js
index 9294ac099e965f000734794c2dd48bfd35b6d9a1..b23025d3545a82e50a4cd29e533b760e082fbbd7 100644
--- a/calendar.js
+++ b/calendar.js
@@ -13,7 +13,7 @@ export default class DatePickView extends Component {
   }
 
   componentWillUnmount() {
-    bleedingDaysSortedByDate.removeListener(setStateWithCalendarFormattedDays)
+    bleedingDaysSortedByDate.removeAllListeners()
   }
 
   passDateToDayView(result) {
diff --git a/day-view.js b/day-view.js
index 0d4e45cb8d386eb40264a36cb052e622f75c3ccf..037521931e65b78649cf2440286b6166c93b7dc7 100644
--- a/day-view.js
+++ b/day-view.js
@@ -7,19 +7,28 @@ import {
 import styles from './styles'
 import { formatDateForViewHeader } from './format'
 import { bleeding as labels} from './labels'
-import getCycleDay from './get-cycle-day'
+import cycleDayModule from './get-cycle-day-number'
+import { bleedingDaysSortedByDate } from './db'
+
+const getCycleDayNumber = cycleDayModule()
 
 export default class DayView extends Component {
   constructor(props) {
     super(props)
+    this.cycleDay = props.navigation.state.params.cycleDay
     this.state = {
-      cycleDay: props.navigation.state.params.cycleDay
+      cycleDayNumber: getCycleDayNumber(this.cycleDay.date),
     }
+    bleedingDaysSortedByDate.addListener(setStateWithCurrentCycleDayNumber.bind(this))
+  }
+
+  componentWillUnmount() {
+    bleedingDaysSortedByDate.removeAllListeners()
   }
 
   render() {
     const navigate = this.props.navigation.navigate
-    const cycleDay = this.state.cycleDay
+    const cycleDay = this.cycleDay
     const bleedingValue = cycleDay.bleeding && cycleDay.bleeding.value
     let bleedingLabel
     if (typeof bleedingValue === 'number') {
@@ -40,7 +49,7 @@ export default class DayView extends Component {
     return (
       <View style={styles.container}>
         <Text style={styles.welcome}>{formatDateForViewHeader(cycleDay.date)}</Text>
-        <Text>Cycle day {getCycleDay()}</Text>
+        <Text>Cycle day {getCycleDayNumber(cycleDay.date)}</Text>
         <Text style={styles.welcome}>{bleedingLabel}</Text>
         <Text style={styles.welcome}>{temperatureLabel}</Text>
         <Button
@@ -54,4 +63,10 @@ export default class DayView extends Component {
       </View >
     )
   }
+}
+
+function setStateWithCurrentCycleDayNumber() {
+  this.setState({
+    cycleDayNumber: getCycleDayNumber(this.cycleDay.date)
+  })
 }
\ No newline at end of file
diff --git a/db.js b/db.js
index 8f34199cb1cffb5f6c505be25c3ffafc6094b286..a469530553835f226e4266aec0348fbb282d4e13 100644
--- a/db.js
+++ b/db.js
@@ -1,10 +1,6 @@
-import realm from 'realm'
+import Realm from 'realm'
 import { LocalDate } from 'js-joda'
 
-let db
-let cycleDaysSortedbyDate = []
-let bleedingDaysSortedByDate = []
-let temperatureDaysSortedByDate
 
 const TemperatureSchema = {
   name: 'Temperature',
@@ -38,21 +34,18 @@ const CycleDaySchema = {
   }
 }
 
-async function openDatabase() {
-  db = await realm.open({
-    schema: [
-      CycleDaySchema,
-      TemperatureSchema,
-      BleedingSchema
-    ],
-    // we only want this in dev mode
-    deleteRealmIfMigrationNeeded: true
-  })
+const db = new Realm({
+  schema: [
+    CycleDaySchema,
+    TemperatureSchema,
+    BleedingSchema
+  ],
+  // we only want this in dev mode
+  deleteRealmIfMigrationNeeded: true
+})
 
-  cycleDaysSortedbyDate = db.objects('CycleDay').sorted('date', true)
-  bleedingDaysSortedByDate = db.objects('CycleDay').filtered('bleeding != null').sorted('date', true)
-  temperatureDaysSortedByDate = db.objects('CycleDay').filtered('temperature != null').sorted('date', true)
-}
+const bleedingDaysSortedByDate = db.objects('CycleDay').filtered('bleeding != null').sorted('date', true)
+const temperatureDaysSortedByDate = db.objects('CycleDay').filtered('temperature != null').sorted('date', true)
 
 function saveTemperature(cycleDay, temperature) {
   db.write(() => {
@@ -60,6 +53,8 @@ function saveTemperature(cycleDay, temperature) {
   })
 }
 
+const getCycleDaysSortedByDateView = () => db.objects('CycleDay').sorted('date', true)
+
 function saveBleeding(cycleDay, bleeding) {
   db.write(() => {
     cycleDay.bleeding = bleeding
@@ -78,6 +73,12 @@ function getOrCreateCycleDay(localDate) {
   return result
 }
 
+function deleteAll() {
+  db.write(() => {
+    db.deleteAll()
+  })
+}
+
 function getPreviousTemperature(cycleDay) {
   cycleDay.wrappedDate = LocalDate.parse(cycleDay.date)
   const winner = temperatureDaysSortedByDate.find(day => {
@@ -89,11 +90,11 @@ function getPreviousTemperature(cycleDay) {
 }
 
 export {
-  cycleDaysSortedbyDate,
-  openDatabase,
   saveTemperature,
   saveBleeding,
   getOrCreateCycleDay,
   bleedingDaysSortedByDate,
+  getCycleDaysSortedByDateView,
+  deleteAll,
   getPreviousTemperature
 }
diff --git a/get-cycle-day-number.js b/get-cycle-day-number.js
new file mode 100644
index 0000000000000000000000000000000000000000..90646e46acc02d44bc4db5709a58df5aa934b3ee
--- /dev/null
+++ b/get-cycle-day-number.js
@@ -0,0 +1,48 @@
+import * as joda from 'js-joda'
+
+const LocalDate = joda.LocalDate
+
+export default function config(opts = {}) {
+  let bleedingDaysSortedByDate
+  if (!opts.bleedingDaysSortedByDate) {
+    // we only want to require (and run) the db module when not running the tests
+    bleedingDaysSortedByDate = require('./db').bleedingDaysSortedByDate
+  } else {
+    bleedingDaysSortedByDate = opts.bleedingDaysSortedByDate
+  }
+  const maxBreakInBleeding = opts.maxBreakInBleeding || 1
+
+  return function getCycleDayNumber(targetDateString) {
+    const targetDate = LocalDate.parse(targetDateString)
+    const withWrappedDates = bleedingDaysSortedByDate
+      .filter(day => !day.bleeding.exclude)
+      .map(day => {
+        day.wrappedDate = LocalDate.parse(day.date)
+        return day
+      })
+
+    const firstBleedingDayBeforeTargetDayIndex = withWrappedDates.findIndex(day => {
+      return (
+        day.wrappedDate.isEqual(targetDate) ||
+        day.wrappedDate.isBefore(targetDate)
+      )
+    })
+
+    if (firstBleedingDayBeforeTargetDayIndex < 0) return null
+    const previousBleedingDays = withWrappedDates.slice(firstBleedingDayBeforeTargetDayIndex)
+
+    const lastPeriodStart = previousBleedingDays.find((day, i) => {
+      return thereIsNoPreviousBleedingDayWithinTheThreshold(day, previousBleedingDays.slice(i + 1), maxBreakInBleeding)
+    })
+
+    const diffInDays = lastPeriodStart.wrappedDate.until(targetDate, joda.ChronoUnit.DAYS)
+
+    // cycle starts at day 1
+    return diffInDays + 1
+  }
+}
+
+function thereIsNoPreviousBleedingDayWithinTheThreshold(bleedingDay, earlierCycleDays, allowedBleedingBreak) {
+  const periodThreshold = bleedingDay.wrappedDate.minusDays(allowedBleedingBreak + 1)
+  return !earlierCycleDays.some(({ wrappedDate }) => wrappedDate.equals(periodThreshold) || wrappedDate.isAfter(periodThreshold))
+}
\ No newline at end of file
diff --git a/get-cycle-day.js b/get-cycle-day.js
deleted file mode 100644
index 4930e24ef0663c9fd164f4523d291d7df11dcac0..0000000000000000000000000000000000000000
--- a/get-cycle-day.js
+++ /dev/null
@@ -1 +0,0 @@
-export default () => 6
\ No newline at end of file
diff --git a/home.js b/home.js
index c02055e6f9876a4370443cfd6f28e18f3713265c..9ae59176a70ae1e4b44caa4d4898308c0891dc27 100644
--- a/home.js
+++ b/home.js
@@ -6,12 +6,26 @@ import {
 } from 'react-native'
 import { LocalDate } from 'js-joda'
 import styles from './styles'
-import getCycleDay from './get-cycle-day'
-import { getOrCreateCycleDay } from './db'
+import cycleDayModule from './get-cycle-day-number'
+import { getOrCreateCycleDay, bleedingDaysSortedByDate, deleteAll } from './db'
+
+const getCycleDayNumber = cycleDayModule()
 
 export default class Home extends Component {
   constructor(props) {
     super(props)
+    this.todayDateString = LocalDate.now().toString()
+    const cycleDayNumber = getCycleDayNumber(this.todayDateString)
+
+    this.state = {
+      welcomeText: determineWelcomeText(cycleDayNumber)
+    }
+
+    bleedingDaysSortedByDate.addListener(setStateWithCurrentWelcomeText.bind(this))
+  }
+
+  componentWillUnmount() {
+    bleedingDaysSortedByDate.removeAllListeners()
   }
 
   passTodayToDayView() {
@@ -25,7 +39,7 @@ export default class Home extends Component {
     const navigate = this.props.navigation.navigate
     return (
       <View style={styles.container}>
-        <Text style={styles.welcome}>Welcome! Today is day {getCycleDay()} of your current cycle</Text>
+        <Text style={styles.welcome}>{this.state.welcomeText}</Text>
         <Button
           onPress={() => this.passTodayToDayView()}
           title="Edit symptoms for today">
@@ -34,7 +48,21 @@ export default class Home extends Component {
           onPress={() => navigate('calendar')}
           title="Go to calendar">
         </Button>
+        <Button
+          onPress={() => deleteAll()}
+          title="delete everything">
+        </Button>
       </View>
     )
   }
 }
+
+function determineWelcomeText(cycleDayNumber) {
+  const welcomeTextWithCycleDay = `Welcome! Today is day ${cycleDayNumber} of your current cycle`
+  const welcomeText = `Welcome! We don't have enough information to know what your current cycle day is`
+  return cycleDayNumber ? welcomeTextWithCycleDay : welcomeText
+}
+
+function setStateWithCurrentWelcomeText() {
+  this.setState({ welcomeText: determineWelcomeText(getCycleDayNumber(this.todayDateString)) })
+}
diff --git a/index.js b/index.js
index f1543b7f59a076d1539af1d4567760115840d236..408a2f0a4f5c4eca1c780a50f05b467785c97608 100644
--- a/index.js
+++ b/index.js
@@ -1,9 +1,4 @@
 import { AppRegistry } from 'react-native'
-import Home from './app'
-import { openDatabase } from './db'
+import App from './app'
 
-// TODO error handling
-openDatabase()
-  .then(() => {
-    AppRegistry.registerComponent('home', () => Home)
-  })
\ No newline at end of file
+AppRegistry.registerComponent('home', () => App)
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 615ce54dd05f5890170a089e44d6d40713d19a22..4ec7dc76bc631480f8574c0f4d9ea2c2f2d02351 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2766,6 +2766,12 @@
       "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
       "dev": true
     },
+    "dirty-chai": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-2.0.1.tgz",
+      "integrity": "sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w==",
+      "dev": true
+    },
     "doctrine": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
diff --git a/package.json b/package.json
index 98d3dae7b46ea994138777d56c6ee4c9f84ed9d1..ff64b52e0e0accea0b3fb9ce537356b24681353d 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
   "devDependencies": {
     "babel-preset-react-native": "4.0.0",
     "chai": "^4.1.2",
+    "dirty-chai": "^2.0.1",
     "eslint": "^4.19.1",
     "eslint-plugin-react": "^7.8.2",
     "mocha": "^5.2.0",
diff --git a/temperature.js b/temperature.js
index ba7121c5d23a7e5f2491897faed0d08c263076e3..5e2f00a94c09bb6ff435e0e3aeb691b91fdf9db6 100644
--- a/temperature.js
+++ b/temperature.js
@@ -10,7 +10,9 @@ import {
 import styles from './styles'
 import { saveTemperature, getPreviousTemperature } from './db'
 import { formatDateForViewHeader } from './format'
-import getCycleDay from './get-cycle-day'
+import cycleDayModule from './get-cycle-day-number'
+
+const getCycleDayNumber = cycleDayModule()
 
 export default class Temp extends Component {
   constructor(props) {
@@ -37,7 +39,7 @@ export default class Temp extends Component {
     return (
       <View style={styles.container}>
         <Text style={styles.welcome}>{formatDateForViewHeader(cycleDay.date)}</Text>
-        <Text>Cycle day {getCycleDay()}</Text>
+        <Text>Cycle day {getCycleDayNumber()}</Text>
         <Text>Temperature</Text>
         <TextInput
           placeholder="Enter temperature"
diff --git a/test/app.spec.js b/test/app.spec.js
deleted file mode 100644
index 019e3fa032f7b89dcec2c4d8e8e7fc3b4d4111c5..0000000000000000000000000000000000000000
--- a/test/app.spec.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import { expect } from 'chai'
-
-it('says hello world', function () {
-  expect(1 + 5).to.eql(6)
-})
diff --git a/test/get-cycle-day.spec.js b/test/get-cycle-day.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..222d62e95fdf92ba56085fac0738310176cba2a9
--- /dev/null
+++ b/test/get-cycle-day.spec.js
@@ -0,0 +1,146 @@
+import chai from 'chai'
+import dirtyChai from 'dirty-chai'
+
+const expect = chai.expect
+chai.use(dirtyChai)
+
+import getCycleDayNumberModule from '../get-cycle-day-number'
+
+describe('getCycleDay', () => {
+  it('works for a simple example', function () {
+    const bleedingDays = [{
+      date: '2018-05-10',
+      bleeding: {
+        value: 2
+      }
+    }, {
+      date: '2018-05-09',
+      bleeding: {
+        value: 2
+      }
+    }, {
+      date: '2018-05-03',
+      bleeding: {
+        value: 2
+      }
+    }]
+    const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays})
+    const targetDate = '2018-05-17'
+    const result = getCycleDayNumber(targetDate)
+    expect(result).to.eql(9)
+  })
+
+  it('works if some bleedings are exluded', function () {
+    const bleedingDays = [{
+      date: '2018-05-10',
+      bleeding: {
+        value: 2,
+        exclude: true
+      }
+    }, {
+      date: '2018-05-09',
+      bleeding: {
+        value: 2,
+        exclude: true
+      }
+    }, {
+      date: '2018-05-03',
+      bleeding: {
+        value: 2
+      }
+    }]
+    const targetDate = '2018-05-17'
+    const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays})
+    const result = getCycleDayNumber(targetDate)
+    expect(result).to.eql(15)
+  })
+
+  it('gets the correct number if the target day is not in the current cycle', () => {
+    const bleedingDays = [{
+      date: '2018-05-13',
+      bleeding: {
+        value: 2
+      }
+    }, {
+      date: '2018-04-11',
+      bleeding: {
+        value: 2
+      }
+    }, {
+      date: '2018-04-10',
+      bleeding: {
+        value: 2
+      }
+    }]
+
+    const targetDate = '2018-04-27'
+    const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays})
+    const result = getCycleDayNumber(targetDate)
+    expect(result).to.eql(18)
+  })
+
+  it('gets the correct number if the target day is the only bleeding day', () => {
+    const bleedingDays = [{
+      date: '2018-05-13',
+      bleeding: {
+        value: 2
+      }
+    }]
+
+    const targetDate = '2018-05-13'
+    const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays})
+    const result = getCycleDayNumber(targetDate)
+    expect(result).to.eql(1)
+  })
+})
+
+describe('getCycleDay returns null', () => {
+  it('if there are no bleeding days', function () {
+    const bleedingDays = []
+    const targetDate = '2018-05-17'
+    const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays})
+    const result = getCycleDayNumber(targetDate)
+    expect(result).to.be.null()
+  })
+})
+
+describe('getCycleDay with cycle thresholds', () => {
+  const maxBreakInBleeding = 3
+
+  it('disregards bleeding breaks shorter than max allowed bleeding break in a bleeding period', () => {
+    const bleedingDays = [{
+      date: '2018-05-14',
+      bleeding: {
+        value: 2
+      }
+    }, {
+      date: '2018-05-10',
+      bleeding: {
+        value: 2
+      }
+    }]
+
+    const targetDate = '2018-05-17'
+    const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays, maxBreakInBleeding })
+    const result = getCycleDayNumber(targetDate)
+    expect(result).to.eql(8)
+  })
+
+  it('counts bleeding breaks longer than maxAllowedBleedingBreak in a bleeding period', () => {
+    const bleedingDays = [{
+      date: '2018-05-14',
+      bleeding: {
+        value: 2
+      }
+    }, {
+      date: '2018-05-09',
+      bleeding: {
+        value: 2
+      }
+    }]
+    const targetDate = '2018-05-17'
+    const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays, maxBreakInBleeding })
+    const result = getCycleDayNumber(targetDate)
+    expect(result).to.eql(4)
+  })
+})
\ No newline at end of file