Any ideas on how I can re-format this expression to not return an error?
Z In-Yr Rate Inc. (Contract Eff.) =
IF (
'Sales Force_Opportunity'[Z In-Yr Rate Inc. (by Close Dt. Yr)] = "",
"",
'Sales Force_Opportunity'[Contract_Effective_Date__c]
)
Here's the error
Expressions that yield variant data-type cannot be used to define calculated columns
NOTE: 'sales force opportunity Z in-yr rate inc (by close dt yr) is a whole number and needs to be a whole number if possible
As the error message indicates, you are returning different data types with your expression:
If True: return a string
If False: return a date
This doesn't work. You have return a date in both cases like so:
Z In-Yr Rate Inc. (Contract Eff.) =
IF (
'Sales Force_Opportunity'[Z In-Yr Rate Inc. (by Close Dt. Yr)] = "",
DATE(2000, 1, 1),
'Sales Force_Opportunity'[Contract_Effective_Date__c]
)
Related
We have a report connected, via a live connection, to an analysis services tabular model.
We have this measure:
MeasureX=
VAR NumLogins =
CALCULATE (
[Measure Dynamic Agg],
'Time Periods'[PeriodCalc] = "Current MtD",
'Calendar'[Is Current Month] = "TRUE",
'Measures - Financial Agg'[Formula] = "Num Logins",
ALL ( 'Measures - Financial'[Formula] )
)
VAR NumCategories =
CALCULATE (
[Measure Dynamic],
'Time Periods'[PeriodCalc] = "Current MtD",
'Calendar'[Is Current Month] = "TRUE",
'Measures - Financial'[Formula] = "Num Categories",
ALL ( 'Measures - Financial Agg'[Formula] )
)
RETURN
DIVIDE(NumLogins ,NumCategories)
In the dashboard this returns blanks everywhere.
If we change the last line of DAX to the following it returns numbers as expected:
...
...
RETURN
NumLogins / NumCategories
Does anyone have any clue what is happening? I was under the impression that semantically using the / operator and DIVIDE function were the same, apart from handling divide by zero differently?
DIVIDE handles both zeroes and blanks in the denominator. It's the blanks that are getting you here. Check out https://learn.microsoft.com/en-us/dax/best-practices/dax-divide-function-operator.
I want to display all cars that were manucfactured after 1997.
How can it be done using nothing than queries?
These are the predicates
/* type(type reference, type of car) */
car_type(01,hatchback).
car_type(02,van).
car_type(03,off_road).
/* car(make ref, type ref, model, reg no, colour, year) */
car(01,01,escort,fsd127,blue,1999).
car(07,01,uno,tre333,blue,1996).
car(02,03,discovery,uje777,red,1995).
car(03,01,starlet,uij236,green,1991).
car(01,02,transit,ski432,green,1991).
car(07,01,bravo,juy677,red,1998).
Below is the query I inputted.
?- car(_,TYPE_REF,_,_,_,(X#>1997)),
car_type(TYPE_REF, TYPE_OF_CARS)
With the error being
false
I want to see the following output
1999 HATCHBACK
1998 HATCHBACK
Your problem is that Prolog does not evaluate arguments inside queries (the procedure you are querying may evaluate them though, but is not what happens in your fact-based source).
So you are passing the term (X#>1997) as the last argument to car/6 which will not unify with any fact.
You may instead use a free variable to query every car and then constrain the value it is bound to:
?- car(_,TYPE_REF,_,_,_,Year), Year > 1997, car_type(TYPE_REF, TYPE_OF_CARS).
TYPE_REF = 1,
Year = 1999,
TYPE_OF_CARS = hatchback ;
TYPE_REF = 1,
Year = 1998,
TYPE_OF_CARS = hatchback.
Or you may start using CLP(fd) and add the constraint first:
?- Year #> 1997, car(_,TYPE_REF,_,_,_,Year), car_type(TYPE_REF, TYPE_OF_CARS).
Year = 1999,
TYPE_REF = 1,
TYPE_OF_CARS = hatchback ;
Year = 1998,
TYPE_REF = 1,
TYPE_OF_CARS = hatchback.
Mine is tablix report, with columns and values. Which are dynamically generating.
Issue is, there are some date and numeric columns which i want to format, and for that i am trying below given expressions:
=IIf(Fields!ColumnName.Value = "Charge",
FormatCurrency(Fields!Value.Value, 2),
IIf(Fields!ColumnName.Value = "StartDate",
FORMAT(CDate(Fields!Value.Value),"MM-dd-yyyy"),
IIf(Fields!ColumnName.Value = "EndDate",
FORMAT(CDate(Fields!Value.Value),"MM-dd-yyyy"),
Fields!Value.Value
)
)
)
OR
=Switch
(
Fields!ColumnName.Value = "Charge", FormatCurrency(Fields!Value.Value, 2),
Fields!ColumnName.Value = "StartDate", FORMAT(CDate(Fields!Value.Value),"MM-dd-yyyy"),
Fields!ColumnName.Value = "EndDate", FORMAT(CDate(Fields!Value.Value),"MM-dd-yyyy"),
true, Fields!Value.Value
)
OR
=IIF(IsNumeric(Fields!Value.Value), FormatNumber(Fields!Value.Value, 2), Fields!Value.Value)
none of them are working, it changes the number columns correctly and then it gives #Error in every columns.
Add the following custom code to your report
Public Function FormatColumn(columnName As String, value AS String) As String
Select columnName
Case "Charge"
Return Format(CLng(value), "c2")
Case "StartDate"
Return Format(CDate(value),"MM-dd-yyyy")
Case "EndDate"
Return Format(CDate(value),"MM-dd-yyyy")
Case Else
Return value
End Select
End Function
Set the cell expression to
= Code.FormatColumn(Fields!ColumnName.Value,Fields!value.Value)
The topic at hand is a messy domain-specific problem working with dates in Oracle's ERP software called JD Edwards. Its detail is documented in this question.
Before writing wrapper classes for handling the dates and times from JD Edwards, I want to know if JodaTime or Java 8 introduced any special support for this unique time format, or if I'll have to do significant string manipulation regardless of the libraries I use.
This is an obscure problem, so please only respond if you have specific knowledge of this problem, and/or JodaTime/Java 8/JSR 310.
ADDITION:
Per Basil Bourque's request, adding example of timestamps that accompany said dates. Here are two example of date/time fields from different tables:
JCSBMDATE:115100, JCSBMTIME:120102.0
RLUPMJ:114317, RLUPMT:141805.0
Also, the date variable is being cast as a BigDecimal and the time is a Double. So, I'll probably keep the string parsers around, but also write factory methods that take the BigDecimal/Double values natively as well.
It seems that the time field is actually the number of Milliseconds (not seconds) from the start of the day, and the ".0" can be ignored. So, one will have to perform a conversion and calculation like so:
localDate.atTime(LocalTime.ofNanoOfDay(Long.parseLong(jdeTime) * 1000000))
JD Edwards date defined
Actually the detail of a JD Edwards date is not so gory, according to this simple description on a page at Oracle.com:
About the Julian Date Format
Date fields in JD Edwards World files are stored in the Julian format. …
The Julian (*JUL) date format is CYYDDD, where:
C is added to 19 to create the century, i.e. 0 + 19 = 19, 1 + 19 = 20. YY is the year within the century, DDD is the day in the year.
Terms:
I would call the C part a “century-offset”, how many centuries to add to 19. Use 0 for 19xx years, and 1 for 20xx years.
The java.time framework calls the DDD a “DayOfYear”, and “ordinal date” is another term. The use of “Julian” for a day-number-within-a-year is common but not correct, conflicting with a Julian Day.
The java.time framework does not include direct support for parsing or generating strings of this format, not that I can find.
JulianFields
There is the java.time.temporal.JulianFields but those are for an redefined version of Julian dates where we count the number of days from an epoch (1970-01-01 (ISO) rather than the historic November 24, 4714 BC (proleptic Gregorian)), while ignoring years altogether. So this has nothing to do with the JD Edwards definition, contrary to some incorrect advice on that page linked in the Question.
Ordinal Date
This JD Edwards date is a version of an ordinal date. The ordinal date is sometimes referred to casually (and incorrectly) as a "julian" date only because it shares the idea of counting a sequence of days. But an ordinal date counts days from the beginning of the year to end of year for a number always between 1 and 365/366 (leap year), not counting since some epoch and growing into a number into the thousands.
Back to the Question, handling the JD Edwards date in java.time…
No, I do not find any direct or indirect support the JD Edwards date built into java.time.
The java.date.format package seems unaware of the century of a date, only the year and the era. So no way that I can find to define the C part of a JD Edwards date.
The last part of a JD Edwards date, the ordinal number of days in the year, is well-handled with within both the date-time classes and the formatting classes.
Wrap LocalDate
Since a JD Edwards date apparently has the same logic as the ISO chronology used by java.time, the only real issue at hand is parsing and generating String objects according to this particular format. All other behavior can be leveraged from a LocalDate.
Since I cannot find a way to define a java.time.format.DateTimeFormatter for this purpose, I suggest writing a utility class to handle these chores.
Ideally we would extend the LocalDate class, overriding its parse and toString methods. And perhaps a getCenturyOffset method. But the LocalDate class is marked final and cannot be extended. So I would create something like this class shown below, wrapping a LocalDate.
CAVEAT: Use at your own risk. Fresh code, barely run, hardly tested. Meant as an example, not for use in production. Use according to terms of the ISC License.
package com.example.whatever;
import java.time.LocalDate;
import java.time.ZoneId;
/**
* Wraps a 'LocalDate' to provide parsing/generating of strings in format known
* as JD Edwards date.
*
* Format is CYYDDD where C is the number of centuries from 1900, YY is the year
* within that century, and DDD is the ordinal day within the year (1-365 or
* 1-366 in Leap Year).
*
* Immutable object. Thread-safe (hopefully! No guarantees).
*
* I would rather have done this by extending the 'java.time.LocalDate' class, but that class is marked 'final'.
*
* Examples: '000001' is January 1 of 1900. '116032' is February 1, 2016.
*
* © 2016 Basil Bourque. This source code may be used according to terms of the ISC License at https://opensource.org/licenses/ISC
*
* #author Basil Bourque
*/
public class JDEdwardsLocalDate {
private LocalDate localDate = null;
private int centuryOffset;
private int yearOfCentury;
private String formatted = null;
// Static Factory method, in lieu of public constructor.
static public JDEdwardsLocalDate from ( LocalDate localDateArg ) {
return new JDEdwardsLocalDate ( localDateArg );
}
// Static Factory method, in lieu of public constructor.
static public JDEdwardsLocalDate parse ( CharSequence charSequenceArg ) {
if ( null == charSequenceArg ) {
throw new IllegalArgumentException ( "Passed CharSequence that is null. Message # 0072f897-b05f-4a0e-88d9-57cfd63a712c." );
}
if ( charSequenceArg.length () != 6 ) {
throw new IllegalArgumentException ( "Passed CharSequence that is not six characters in length. Message # eee1e134-8ec9-4c92-aff3-9296eac1a84a." );
}
String string = charSequenceArg.toString ();
// Should have all digits. Test by converting to an int.
try {
int testAsInteger = Integer.parseInt ( string );
} catch ( NumberFormatException e ) {
throw new IllegalArgumentException ( "Passed CharSequence contains non-digits. Fails to convert to an integer value. Message # 0461f0ee-b6d6-451c-8304-6ceface05332." );
}
// Validity test passed.
// Parse.
int centuryOffset = Integer.parseInt ( string.substring ( 0 , 1 ) ); // Plus/Minus from '19' (as in '1900').
int yearOfCentury = Integer.parseInt ( string.substring ( 1 , 3 ) );
int ordinalDayOfYear = Integer.parseInt ( string.substring ( 3 ) );
int centuryStart = ( ( centuryOffset + 19 ) * 100 ); // 0 -> 1900. 1 -> 2000. 2 -> 2100.
int year = ( centuryStart + yearOfCentury );
LocalDate localDate = LocalDate.ofYearDay ( year , ordinalDayOfYear );
return new JDEdwardsLocalDate ( localDate );
}
// Constructor.
private JDEdwardsLocalDate ( LocalDate localDateArg ) {
this.localDate = localDateArg;
// Calculate century offset, how many centuries plus/minus from 1900.
int year = this.localDate.getYear ();
int century = ( year / 100 );
this.yearOfCentury = ( year - ( century * 100 ) ); // example: if 2016, return 16.
this.centuryOffset = ( century - 19 );
// Format as string.
String paddedYearOfCentury = String.format ( "%02d" , this.yearOfCentury );
String paddedDayOfYear = String.format ( "%03d" , this.localDate.getDayOfYear () );
this.formatted = ( this.centuryOffset + paddedYearOfCentury + paddedDayOfYear );
}
#Override
public String toString () {
return this.formatted;
}
public LocalDate toLocalDate () {
// Returns a java.time.LocalDate which shares the same ISO chronology as a JD Edwards Date.
return this.localDate;
}
public int getDayOfYear () {
// Returns ordinal day number within the year, 1-365 inclusive or 1-366 for Leap Year.
return this.localDate.getDayOfYear();
}
public int getYear () {
// Returns a year number such as 2016.
return this.localDate.getYear();
}
public int getYearOfCentury () {
// Returns a number within 0 and 99 inclusive.
return this.yearOfCentury;
}
public int getCenturyOffset () {
// Returns 0 for 19xx dates, 1 for 20xx dates, 2 for 21xx dates, and so on.
return this.centuryOffset;
}
public static void main ( String[] args ) {
// '000001' is January 1, 1900.
JDEdwardsLocalDate jde1 = JDEdwardsLocalDate.parse ( "000001" );
System.out.println ( "'000001' = JDEdwardsLocalDate: " + jde1 + " = LocalDate: " + jde1.toLocalDate () + " Should be: January 1, 1900. " );
// '116032' is February 1, 2016.
JDEdwardsLocalDate jde2 = JDEdwardsLocalDate.parse ( "116032" );
System.out.println ( "'116032' = JDEdwardsLocalDate: " + jde2 + " = LocalDate: " + jde2.toLocalDate () + " Should be: February 1, 2016." );
// Today
LocalDate today = LocalDate.now ( ZoneId.systemDefault () );
JDEdwardsLocalDate jdeToday = JDEdwardsLocalDate.from ( today );
System.out.println ( "LocalDate.now(): " + today + " = JDEdwardsLocalDate: " + jdeToday + " to LocalDate: " + jdeToday.toLocalDate () );
}
}
When run.
'000001' = JDEdwardsLocalDate: 000001 = LocalDate: 1900-01-01 Should be: January 1, 1900.
'116032' = JDEdwardsLocalDate: 116032 = LocalDate: 2016-02-01 Should be: February 1, 2016.
LocalDate.now(): 2016-05-09 = JDEdwardsLocalDate: 116130 to LocalDate: 2016-05-09
JD Edwards time-of-day
As for JD Edwards time-of-day formats, I searched and could not find any documentation. If you know of some, please edit your Question to add links. The only mentions of JDE times seemed to be a count of seconds from midnight.
If that is the case (a count since midnight), the java.time.LocalTime class has you covered. A LocalTime can be instantiated and read as either:
Whole seconds since start of day ( withSecond, ofSecondOfDay )
Fractional seconds since start of day, with a resolution of nanoseconds ( withNano, ofNanoOfDay )
Nanosecond resolution means up to nine digits of a decimal fraction. No problem handling the six digits you mentioned. Just do the math, multiply/divide by 1_000L. Just be aware that means possible data loss as you could be truncating those last three digits of fraction (7th, 8th, 9th digits of decimal fraction) if the LocalTime value came from outside of JD Edwards data. [FYI, the old java.util.Date/.Calendar classes, as well as Joda-Time, are limited to milliseconds resolution, for three digits of decimal fraction.]
Not recommended: You could do some kind of combo class, composed of a LocalDate and a LocalTime. Or use a LocalDateTime. The key issue is time zone. If a JD Edwards date-time is always in a certain time zone such as UTC, then it might make sense to combine and use an OffsetDateTime . But if it has no specific time zone context, if the values are just a fuzzy idea of a date-time rather than specific points on the timeline, then use LocalDateTime as it has no time zone. If a JDE is always in UTC, use OffsetDateTime set to ZoneOffset.UTC. If you want to specify a time zone (an offset plus rules for handling anomalies such as DST), use ZonedDateTime.
Recommended: Use a LocalTime separately. I do not think you want to be using my JDEdwardsLocalDate class in your business logic, especially because it is not a full implementation fitting into the java.time framework. My intention is to use that class to immediately convert to LocalDate when you encounter a JDE date. Same goes for a JDE time-of-day, convert to LocalTime immediately. If their context is always UTC, create an OffsetDateTime with UTC, and then pass that around your business logic. Only go back to a JDE date & time when necessary (persisting to database column of that JDE type, or reporting to user expecting that JDE presentation).
OffsetDateTime odt = OffsetDateTime.of( myLocalDate , myLocalTime , ZoneOffset.UTC );
If the JDE date & time has some other context implied, then assign the intended time zone.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( myLocalDate , myLocalTime , zoneId );
Time zone is crucial here. You must understand the concepts in general. Be clear that LocalDate and LocalTime and LocalDateTime are not a moment on the timeline. They have no specific meaning until you adjust them into a time zone (or at least an offset-from-UTC).
My diagram of date-time types included on this Answer may help you if not familiar with the java.time types.
And you must understand the meaning of JDE date & time and their use in your apps/databases. As I could not find anything about JDE time, I could not learn anything about the JD Edwards intentions towards time zones. So I cannot suggest anything more specific.
No: Neither Joda Time nor Java 8 have support for JD Edwards time representations.
I have a panel dataset (country-year) in Stata. For instance I have GDP in 1990,1991,..2010 for many countries.
I want to define a variable "GDP in 2006" which exists for all years and contains the 2006 value of GDP.
The way I am doing it now works but is a but clumsy so I was hoping someone would have a better idea:
qui gen gdp2006=.
replace gdp2006=gdp if year==2006
forval t=2007/2010 {
sort country year
qui replace gdp2006=gdp2006[_n-1] if year==`t'&country[_n-1]==country
}
forval t=2005(-1)1990 {
sort country year
qui replace gdp2006=gdp2006[_n+1] if year==`t'&country[_n+1]==country
}
Thanks!
You can do this in one line
egen gdp2006 = mean(gdp / (year == 2006)), by(country)
(year == 2006) evaluates as 1 or 0, so the expression
gdp / (year == 2006)
evaluates as gdp when year is 2006 and missing otherwise. Missings are ignored in calculating the mean for each country.
For a wider and more systematic discussion see http://www.stata-journal.com/article.html?article=dm0055 (which will be accessible to all in a few weeks from this posting).
P.S. The techniques you know permit shortening of your code:
gen gdp2006 = gdp if year == 2006
bysort country (gdp2006): replace gdp2006 = gdp2006[_n-1] if _n > 1
gen gdp2006_temp = gdp if year == 2006
bys country : egen gdp2006 = total(gdp2006_temp)
drop gdp2006_temp
The key here is to use the by: prefix and the fact that the total() egen function ignores missing values.