Introduktion
Datoer og tidspunkter styrer mange daglige beslutninger i en virksomhed: hvornår blev ordren afgivet, hvornår skal leveringen ske, og hvornår mødte medarbejderen ind? I Odoo bruger man Datetime-feltet til præcist at indfange både dato og tidspunkt, så systemet kan besvare disse spørgsmål entydigt.
Et Datetime-felt indeholder både kalenderdato og klokkeslæt, ikke kun en dag. Det betyder, at du kan registrere hændelser med times- og minutsnøjagtighed — noget der bliver afgørende, hvis brugere arbejder fra forskellige tidszoner eller hvis forretningslogikken afhænger af det præcise øjeblik.
Denne vejledning gennemgår alt relevant omkring Datetime-feltet i Odoo: hvad det gemmer, hvordan det opfører sig i datamodellen, hvordan du opretter det via Studio eller kode, og konkrete eksempler på anvendelse i daglige arbejdsgange.
Hvad er Datetime-feltet i Odoo
I Odoos ORM er Datetime repræsenteret af fields.Datetime og gemmer dato og tid ned til sekundet. I databasen bliver det matchet til en TIMESTAMP-kolonne i PostgreSQL. Internt gemmes altid i UTC; visningen omregnes til den aktuelle brugers tidszone i brugergrænsefladen.
For slutbrugeren vises Datetime som en kombineret dato- og tidsvælger i formularer — en kalender med felt til klokkeslæt. I lister og rapporter formateres værdien ud fra brugerens sprog- og tidszoneindstillinger, så det ser korrekt ud for den enkelte bruger.
Nedenfor ses et eksempel på, hvordan et Datetime-felt defineres i en Python-model i Odoo:
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
x_confirmed_on = fields.Datetime(
string='Confirmed On',
default=fields.Datetime.now,
readonly=True,
copy=False,
)
Parametrene styrer felttitlen (string), standardværdien (default), om brugeren kan rette feltet (readonly) osv. I praksis bruges readonly ofte for tidsstempler, som skal afspejle systemhændelser og ikke være manuelt redigerbare.
I Odoo Studio hedder denne felttype "Date & Time". Felter oprettet fra Studio får tekniske navne med et x_studio_-præfiks automatisk, mens du ved kodning selv bestemmer det tekniske navn.
Hvordan feltet fungerer
Når du definerer et Datetime-felt i modellen, sørger Odoo for at oprette den tilsvarende databasekolonne automatisk ved installation eller opgradering af modulet — du behøver ikke skrive SQL-migrationer manuelt.
Hvad mange bliver overraskede over, er tidszonehåndteringen: værdier gemmes altid i UTC. Hvis en bruger i København sætter et møde til kl. 15:00, gemmes det som 14:00 UTC (afhængig af sommertid). En bruger i en anden tidszone vil se mødet konverteret til deres lokale tid i grænsefladen. Odoo tager sig af disse konverteringer baseret på hver brugers tidszoneindstilling.
Vigtigste feltattributter
Her er de mest centrale egenskaber, du støder på, når du arbejder med Datetime i Odoo:
- default: Anvendes ofte som
fields.Datetime.nowfor automatisk at udfylde feltet med det aktuelle tidspunkt ved oprettelse af en post. - required: Gør feltet obligatorisk i formularer og på modelniveau.
- readonly: Forhindrer manuel redigering i interface — nyttigt til systemgenererede tidsstempler.
- compute: Angiver en Python-metode, som beregner feltets værdi ud fra andre felter eller forretningslogik.
- store: Når det kombineres med
compute, gemmes den beregnede værdi i databasen, så den kan bruges i søgninger og rapporter. - copy: Bestemmer om værdien kopieres ved duplikering af en post. Standard er
True; sæt tilFalsefor tidsstempler, som ikke bør følge med til kopier. - index: Opretter en databaseindeks — relevant for felter, som ofte bruges i filtre på store tabeller, fx planlagte datoer.
Sådan vises feltet i views
I formularer får brugeren en sammenhængende dato- og tidsvælger: kalender til dato og input til klokkeslæt. I lister og rapporter ser man en formateret streng efter brugerens sproglayout. Søgefiltre understøtter typisk tidsintervaler som før, efter eller mellem to tidspunkter.
Du kan også bruge widgets som date_range til at vise og vælge et tidsvindue direkte i formularen — praktisk til planlægning eller tidsbegrænsede opgaver.
Datetime vs Date: Hvad skal du vælge?
Reglen er enkel: vælg fields.Date når kun datoen betyder noget, og fields.Datetime når tidspunktet på dagen er relevant. Overvej om forretningsprocessen virkelig kræver times- eller minutsnøjagtighed.
Brug Date til ting som forfaldsdatoer på fakturaer, fødselsdage, produktudløbsdatoer og kontraktfornyelsesdatoer.
Brug Datetime til hændelsestidspunkter som ordrebekræftelse, møde-start, medarbejderes check-in/out eller planlagte lageroperationer.
At bruge Datetime unødvendigt indfører kun kompleksitet med tidszoner uden værdi. Spørg altid: betyder klokkeslættet noget for denne proces? Hvis nej, vælg Date.
Forretningsscenarier
Hvor Datetime typisk bruges i Odoo
CRM: opfølgning og aktivitetslog
I CRM sporer Datetime-felter hvornår en lead er åbnet, hvornår en opfølgning skal finde sted eller hvornår et tilbud blev sendt. Disse tidsstempler gør det muligt at måle svartider, finde gamle leads og rapportere teamets aktivitet. Tilpassede Datetime-felter kan fange eksakte tidspunkter for opkald eller møder.
Salg: ordrebekræftelse
På salgsposter registrerer et Datetime-felt det præcise øjeblik en ordre blev bekræftet. Det bruges i rapporter for at analysere salg pr. time/dag, måle behandlingstider og lave revision af ændringer efter bekræftelsen. At filtrere ordrer på dette felt er en almindelig rapportdisciplin i salgsmiljøer.
Lager: planlagte forsendelser
I lagerarbejdet bruges Datetime til at planlægge modtagelser og forsendelser. Automatiske workflows kan trigges, hvis en planlagt dato er overskredet — fx udsendelse af notifikationer til kunder, hvis levering er forsinket i et givent antal timer.
Produktion: start- og sluttidspunkter
Produktionsordrer registrerer præcise start- og sluttidspunkter, hvilket er centralt for kapacitetsplanlægning, effektivitet og performanceanalyse. For virksomheder med flere skift er tidspunktsdata nødvendigt for at måle faktisk produktion mod plan og identificere tidspunktsbaserede flaskehalse.
HR: tilstedeværelse og fravær
HR-moduler bruger Datetime til check-in/check-out og til at definere præcise start- og sluttidspunkter for orlov. Lønkørsel og overtidsberegninger afhænger ofte af nøjagtige tidsstempler; manglende eller upræcise værdier kan få direkte lønkonsekvenser.
Opret eller tilpas Datetime-feltet
Tre måder at oprette et Datetime-felt på
Valg af metode afhænger af om du vil bruge en no-code tilgang eller arbejde med kode. Her er de tre mest udbredte måder.
Brug Odoo Studio (ingen kode)
- Odoo Studio er værktøjet til hurtige tilpasninger uden udvikling.
- Åbn Odoo Studio fra hovedmenuen.
- Gå til den formular, hvor feltet skal være.
- Træk en "Date & Time"-felt ind på formularen og konfigurer label, obligatorisk-status og evt. standardværdi i ejendomspanelet.
- Gem og luk Studio.
Studio opretter feltet automatisk med et x_studio_-navn og opdaterer visningen. Ingen database-migration kræves fra din side. Det er den anbefalede fremgangsmåde for forretningen, når du hurtigt skal tilføje tidsstempler uden udviklerindblanding.
Brug Python i et custom modul
For udviklere og teams med versionering anbefales feltdefinition i Python-modellen og visningsændringer i XML:
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_last_contact_date = fields.Datetime(
string='Last Contact Date',
default=fields.Datetime.now,
copy=False,
)
Efter at have defineret feltet i modellen tilføjer du det til den relevante view-XML, så det vises i grænsefladen. Ved installation/opgradering oprettes TIMESTAMP-kolonnen automatisk — ingen manuel SQL nødvendig.
Brug XML-RPC API'en
Hvis du automatiserer konfiguration eller arbejder med et deploymentscript, kan felter også oprettes programmatisk via XML-RPC-API'en.
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_last_contact_date',
'field_description': 'Last Contact Date',
'model_id': model_id,
'ttype': 'datetime',
'state': 'manual',
}]
)
Værdien ttype: 'datetime' angiver Datetime-feltet, og state: 'manual' viser, at feltet er oprettet uden for et modulpakke — korrekt for felter oprettet via Studio eller API i eksterne scripts.
Gode fremgangsmåder
1. Brug fields.Datetime.now som reference, ikke kald funktionen
Når du sætter en default, skal du skrive default=fields.Datetime.now uden parenteser. Tilføjer du parenteser, evalueres tidspunktet én gang ved klasseindlæsning, og alle efterfølgende poster får samme, forkerte stempel.
2. Sæt copy=False på hændelses-tidsstempler
Tidsstempler der dokumenterer hvornår noget skete (fx bekræftelse eller færdiggørelse) bør ikke kopieres ved duplikering af poster. Sæt copy=False, så kopier ikke arver historiske tidspunkter fra originalen.
3. Send altid UTC når du skriver via API'en
Når du skriver Datetime-værdier gennem XML-RPC eller REST, skal du sende tid i UTC i formatet YYYY-MM-DD HH:MM:SS. API'en konverterer ikke ved skrivning — det, du sender, gemmes som UTC, så lokale tider uden konvertering skaber fejl i dataene.
4. Brug readonly for systemgenererede tidsstempler
Systemgenererede tidspunkter bør som regel være skrivebeskyttede i UI, så brugere ikke utilsigtet ændrer audit-loggen. Hvis redigering er nødvendig, styr det gennem adgangsrettigheder fremfor fri redigerbarhed.
5. Vælg Date når tid ikke er relevant
Hvis du kun behøver en kalenderdato, skal du bruge fields.Date. Datetime tilføjer unødvendig tidszonekompleksitet og kan gøre modellen vanskeligere at vedligeholde uden at give værdi.
Almindelige faldgruber
Tidszoneforvirring ved rå database-udlæsning
Et klassisk problem er at læse rå tidsstempler fra databasen eller API'en og tro det er lokal tid — det er det ikke. Rådata viser UTC. Rapporter eller integrationer, der bygger på disse råværdier uden konvertering, får ofte forkerte tidspunkter. Sørg for eksplicit tidszonekonvertering i klienten ved præsentation.
Skrive lokal tid via API'en skaber fejl
Hvis du sender et lokalt tidspunkt til API'en uden at omregne til UTC, gemmes det som om det var UTC. Et møde skrevet som 2026-01-01 15:00:00 vil derfor kunne blive vist forkert for lokale brugere ved sommertidsskift eller forskellige tidszoner — en fejl, der typisk først opdages i produktion.
At bruge default=fields.Datetime.now() med parenteser
Hvis du utilsigtet bruger parenteser i standardværdien, får alle oprettede poster det samme faste tidsstempel — et svært opdageligt, men alvorligt fejltilfælde, fordi tidsstemplerne eksisterer, men er identiske og dermed ubrugelige til historik eller analyse.
Glemme copy=False på hændelsestidsstempler
Uden copy=False følger tidsstempler med ved duplikering, hvilket forurener historik og rapporter. En kopieret ordre bør ikke arve bekræftelsestidspunktet fra sin kilde; ellers bliver revisionsspor og analyser misvisende.
Brug af Datetime når Date havde været nok
Hvis du vælger Datetime for fx fakturaens forfaldsdato, får brugeren unødvendigt et klokkeslæt, og systemet kører tidszoneberegninger uden grund. Hold datamodellen så enkel som muligt: vælg den type der matcher forretningsbehovet.
Konklusion
Sammenfattende er Datetime et af de mest nyttige felttyper i Odoo, når præcision er vigtig. Det bruges i alt fra lead-tracking til produktionslog og timeregistrering.
Det vigtigste at tage med er UTC-princippet: alt gemmes i databasen som UTC, og brugergrænsefladen konverterer til lokal tid. De fleste integrationsfejl omkring tid stammer fra misforståelser omkring dette.
Derudover sørger du for at bruge korrekt default-syntaks, sætte copy=False hvor relevant og vælge Date når tidspunktet ikke betyder noget — så får du en renere datamodel og mere pålidelige rapporter.
Hos Dasolo hjælper vi virksomheder med at implementere og optimere Odoo på tværs af afdelinger. Vi kan assistere med datamodellering, tilpasning af felter eller udvikling af komplette moduler efter behov. Kontakt os så tager vi en dialog om dit Odoo-projekt.